Further API conversion
This commit is contained in:
		
							parent
							
								
									233ee1bf55
								
							
						
					
					
						commit
						1848de0e8d
					
				@ -0,0 +1,92 @@
 | 
				
			|||||||
 | 
					package com.ionspin.kotlin.crypto
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import com.ionspin.kotlin.crypto.hash.MultipartHash
 | 
				
			||||||
 | 
					import com.ionspin.kotlin.crypto.hash.encodeToUByteArray
 | 
				
			||||||
 | 
					import com.ionspin.kotlin.crypto.util.toHexString
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Created by Ugljesa Jovanovic
 | 
				
			||||||
 | 
					 * ugljesa.jovanovic@ionspin.com
 | 
				
			||||||
 | 
					 * on 23-Jun-2020
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					inline class EncryptableString(val content: String) : Encryptable<EncryptableString> {
 | 
				
			||||||
 | 
					    override fun toEncryptableForm(): UByteArray {
 | 
				
			||||||
 | 
					        return content.encodeToUByteArray()
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    override fun fromEncryptableForm(): (UByteArray) -> EncryptableString {
 | 
				
			||||||
 | 
					        return { uByteArray ->
 | 
				
			||||||
 | 
					            EncryptableString(uByteArray.toByteArray().decodeToString())
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fun asString() : String = content
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fun String.asEncryptableString() : EncryptableString {
 | 
				
			||||||
 | 
					    return EncryptableString(this)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					interface Encryptable<T> {
 | 
				
			||||||
 | 
					    fun toEncryptableForm() : UByteArray
 | 
				
			||||||
 | 
					    fun fromEncryptableForm() : (UByteArray) -> T
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					data class HashedData(val hash: UByteArray) {
 | 
				
			||||||
 | 
					    fun toHexString() : String {
 | 
				
			||||||
 | 
					        return hash.toHexString()
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					data class SymmetricKey(val value : UByteArray) {
 | 
				
			||||||
 | 
					    companion object {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					data class EncryptedData constructor(val ciphertext: UByteArray, val nonce: UByteArray) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					interface HashApi {
 | 
				
			||||||
 | 
					    fun hash(data: UByteArray, key : UByteArray = ubyteArrayOf()) : HashedData
 | 
				
			||||||
 | 
					    fun multipartHash(key: UByteArray? = null) : MultipartHash
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					interface EncryptionApi {
 | 
				
			||||||
 | 
					    fun encrypt(key: SymmetricKey, data : Encryptable<*>, additionalData : UByteArray = ubyteArrayOf()) : EncryptedData
 | 
				
			||||||
 | 
					    fun <T: Encryptable<T>> decrypt(key: SymmetricKey, encryptedData : EncryptedData, additionalData: UByteArray, byteArrayDeserializer : (UByteArray) -> T) : T
 | 
				
			||||||
 | 
					    fun multipartEncrypt(key: SymmetricKey, additionalData: UByteArray) : MultipartAuthenticatedEncryption
 | 
				
			||||||
 | 
					    fun multipartDecryptProcessStart(key: SymmetricKey, dataDescriptor: MultipartEncryptedDataDescriptor, additionalData: UByteArray) : MultipartAuthenticatedVerification
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					interface AuthenticatedEncryption {
 | 
				
			||||||
 | 
					    fun encrypt(key: UByteArray, nonce: UByteArray, message: UByteArray, additionalData: UByteArray) : UByteArray
 | 
				
			||||||
 | 
					    fun decrypt(key: UByteArray, nonce: UByteArray, cipherText: UByteArray, additionalData: UByteArray) : UByteArray
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					data class EncryptedDataPart(val data : UByteArray)
 | 
				
			||||||
 | 
					data class DecryptedDataPart(val data : UByteArray)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					data class MultipartEncryptedDataDescriptor(val data: UByteArray, val nonce: UByteArray)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class InvalidTagException : RuntimeException("Tag mismatch! Encrypted data is corrupted or tampered with.")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					interface MultipartAuthenticatedVerification {
 | 
				
			||||||
 | 
					    fun verifyPartialData(data: EncryptedDataPart)
 | 
				
			||||||
 | 
					    fun finalizeVerificationAndPrepareDecryptor() : MultipartAuthenticatedDecryption
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					interface MultipartAuthenticatedDecryption {
 | 
				
			||||||
 | 
					    fun decryptPartialData(data: EncryptedDataPart) : DecryptedDataPart
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					interface MultipartAuthenticatedEncryption {
 | 
				
			||||||
 | 
					    fun encryptPartialData(data: UByteArray) : EncryptedDataPart
 | 
				
			||||||
 | 
					    fun finish() : MultipartEncryptedDataDescriptor
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -5,8 +5,10 @@ package com.ionspin.kotlin.crypto
 | 
				
			|||||||
 * ugljesa.jovanovic@ionspin.com
 | 
					 * ugljesa.jovanovic@ionspin.com
 | 
				
			||||||
 * on 27-May-2020
 | 
					 * on 27-May-2020
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
interface CryptoProvider {
 | 
					interface CryptoInitializer {
 | 
				
			||||||
    suspend fun initialize()
 | 
					    suspend fun initialize()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fun isInitialized() : Boolean
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -0,0 +1,37 @@
 | 
				
			|||||||
 | 
					package com.ionspin.kotlin.crypto
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import com.ionspin.kotlin.crypto.hash.blake2b.Blake2bMultipart
 | 
				
			||||||
 | 
					import com.ionspin.kotlin.crypto.hash.blake2b.Blake2bProperties
 | 
				
			||||||
 | 
					import com.ionspin.kotlin.crypto.hash.sha.Sha256
 | 
				
			||||||
 | 
					import com.ionspin.kotlin.crypto.hash.sha.Sha512
 | 
				
			||||||
 | 
					import com.ionspin.kotlin.crypto.keyderivation.ArgonResult
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Created by Ugljesa Jovanovic
 | 
				
			||||||
 | 
					 * ugljesa.jovanovic@ionspin.com
 | 
				
			||||||
 | 
					 * on 23-Jun-2020
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					interface PrimitivesApi {
 | 
				
			||||||
 | 
					    fun hashBlake2bMultipart(key: UByteArray? = null, hashLength: Int = Blake2bProperties.MAX_HASH_BYTES): Blake2bMultipart
 | 
				
			||||||
 | 
					    fun hashBlake2b(message: UByteArray, key: UByteArray = ubyteArrayOf(), hashLength: Int = Blake2bProperties.MAX_HASH_BYTES): UByteArray
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fun hashSha256Multipart(): Sha256
 | 
				
			||||||
 | 
					    fun hashSha256(message: UByteArray) : UByteArray
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fun hashSha512Multipart(): Sha512
 | 
				
			||||||
 | 
					    fun hashSha512(message: UByteArray) : UByteArray
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fun deriveKey(
 | 
				
			||||||
 | 
					        password: String,
 | 
				
			||||||
 | 
					        salt: String? = null,
 | 
				
			||||||
 | 
					        key: String,
 | 
				
			||||||
 | 
					        associatedData: String,
 | 
				
			||||||
 | 
					        parallelism: Int = 16,
 | 
				
			||||||
 | 
					        tagLength: Int = 64,
 | 
				
			||||||
 | 
					        memory: Int = 4096,
 | 
				
			||||||
 | 
					        numberOfIterations: Int = 10,
 | 
				
			||||||
 | 
					    ) : ArgonResult
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -1,42 +0,0 @@
 | 
				
			|||||||
package com.ionspin.kotlin.crypto.authenticated
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Created by Ugljesa Jovanovic
 | 
					 | 
				
			||||||
 * ugljesa.jovanovic@ionspin.com
 | 
					 | 
				
			||||||
 * on 14-Jun-2020
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
interface Aes256GcmStateless {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    fun encrypt(message: UByteArray, additionalData: UByteArray, rawData : UByteArray, key: Aes256GcmKey) : Aes256GcmEncryptionResult
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    fun decrypt(encryptedData: UByteArray, nonce: UByteArray, key : Aes256GcmKey) : UByteArray
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
data class Aes256GcmEncryptionResult(val cyphertext : UByteArray, val additionalData: UByteArray, val nonce: UByteArray, val tag: UByteArray) {
 | 
					 | 
				
			||||||
    override fun equals(other: Any?): Boolean {
 | 
					 | 
				
			||||||
        if (this === other) return true
 | 
					 | 
				
			||||||
        if (other == null || this::class != other::class) return false
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        other as Aes256GcmEncryptionResult
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if (cyphertext != other.cyphertext) return false
 | 
					 | 
				
			||||||
        if (additionalData != other.additionalData) return false
 | 
					 | 
				
			||||||
        if (nonce != other.nonce) return false
 | 
					 | 
				
			||||||
        if (tag != other.tag) return false
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return true
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    override fun hashCode(): Int {
 | 
					 | 
				
			||||||
        var result = cyphertext.hashCode()
 | 
					 | 
				
			||||||
        result = 31 * result + additionalData.hashCode()
 | 
					 | 
				
			||||||
        result = 31 * result + nonce.hashCode()
 | 
					 | 
				
			||||||
        result = 31 * result + tag.hashCode()
 | 
					 | 
				
			||||||
        return result
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
interface Aes256GcmKey {
 | 
					 | 
				
			||||||
    val key : UByteArray
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,36 +0,0 @@
 | 
				
			|||||||
package com.ionspin.kotlin.crypto.authenticated
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Created by Ugljesa Jovanovic
 | 
					 | 
				
			||||||
 * ugljesa.jovanovic@ionspin.com
 | 
					 | 
				
			||||||
 * on 22-Jun-2020
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
interface AuthenticatedEncryption {
 | 
					 | 
				
			||||||
    fun encrypt(key: UByteArray, nonce: UByteArray, message: UByteArray, additionalData: UByteArray) : UByteArray
 | 
					 | 
				
			||||||
    fun decrypt(key: UByteArray, nonce: UByteArray, cipherText: UByteArray, additionalData: UByteArray) : UByteArray
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
data class EncryptedDataPart(val data : UByteArray)
 | 
					 | 
				
			||||||
data class DecryptedDataPart(val data : UByteArray)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
data class MultipartEncryptedDataDescriptor(val data: UByteArray, val nonce: UByteArray)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
interface MultipartAuthenticatedVerification {
 | 
					 | 
				
			||||||
    fun verifyPartialData(data: EncryptedDataPart)
 | 
					 | 
				
			||||||
    fun finalizeVerificationAndPrepareDecryptor() : MultipartAuthenticatedDecryption
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
interface MultipartAuthenticatedDecryption {
 | 
					 | 
				
			||||||
    fun decryptPartialData(data: EncryptedDataPart) : DecryptedDataPart
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
interface MultipartAuthenticatedEncryption {
 | 
					 | 
				
			||||||
    fun encryptPartialData(data: UByteArray) : EncryptedDataPart
 | 
					 | 
				
			||||||
    fun finish() : MultipartEncryptedDataDescriptor
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@ -27,7 +27,7 @@ interface HashFunction {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
interface MultiPartHash : HashFunction {
 | 
					interface MultipartHash : HashFunction {
 | 
				
			||||||
    fun update(data : UByteArray)
 | 
					    fun update(data : UByteArray)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fun digest() : UByteArray
 | 
					    fun digest() : UByteArray
 | 
				
			||||||
 | 
				
			|||||||
@ -1,7 +1,7 @@
 | 
				
			|||||||
package com.ionspin.kotlin.crypto.hash.blake2b
 | 
					package com.ionspin.kotlin.crypto.hash.blake2b
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import com.ionspin.kotlin.crypto.hash.Hash
 | 
					import com.ionspin.kotlin.crypto.hash.Hash
 | 
				
			||||||
import com.ionspin.kotlin.crypto.hash.MultiPartHash
 | 
					import com.ionspin.kotlin.crypto.hash.MultipartHash
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Created by Ugljesa Jovanovic
 | 
					 * Created by Ugljesa Jovanovic
 | 
				
			||||||
@ -13,12 +13,12 @@ object Blake2bProperties {
 | 
				
			|||||||
    const val MAX_HASH_BYTES = 64
 | 
					    const val MAX_HASH_BYTES = 64
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
interface Blake2b : MultiPartHash {
 | 
					interface Blake2bMultipart : MultipartHash {
 | 
				
			||||||
    override val MAX_HASH_BYTES: Int
 | 
					    override val MAX_HASH_BYTES: Int
 | 
				
			||||||
        get() = Blake2bProperties.MAX_HASH_BYTES
 | 
					        get() = Blake2bProperties.MAX_HASH_BYTES
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
interface Blake2bStateless : Hash {
 | 
					interface Blake2b : Hash {
 | 
				
			||||||
    override val MAX_HASH_BYTES: Int
 | 
					    override val MAX_HASH_BYTES: Int
 | 
				
			||||||
        get() = Blake2bProperties.MAX_HASH_BYTES
 | 
					        get() = Blake2bProperties.MAX_HASH_BYTES
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -1,7 +1,7 @@
 | 
				
			|||||||
package com.ionspin.kotlin.crypto.hash.sha
 | 
					package com.ionspin.kotlin.crypto.hash.sha
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import com.ionspin.kotlin.crypto.hash.Hash
 | 
					import com.ionspin.kotlin.crypto.hash.Hash
 | 
				
			||||||
import com.ionspin.kotlin.crypto.hash.MultiPartHash
 | 
					import com.ionspin.kotlin.crypto.hash.MultipartHash
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Created by Ugljesa Jovanovic
 | 
					 * Created by Ugljesa Jovanovic
 | 
				
			||||||
@ -12,7 +12,7 @@ object Sha256Properties {
 | 
				
			|||||||
    const val MAX_HASH_BYTES = 32
 | 
					    const val MAX_HASH_BYTES = 32
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
interface Sha256 : MultiPartHash {
 | 
					interface Sha256 : MultipartHash {
 | 
				
			||||||
    override val MAX_HASH_BYTES: Int
 | 
					    override val MAX_HASH_BYTES: Int
 | 
				
			||||||
        get() = Sha256Properties.MAX_HASH_BYTES
 | 
					        get() = Sha256Properties.MAX_HASH_BYTES
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -23,4 +23,4 @@ interface StatelessSha256 : Hash {
 | 
				
			|||||||
    fun digest(
 | 
					    fun digest(
 | 
				
			||||||
        inputMessage: UByteArray = ubyteArrayOf()
 | 
					        inputMessage: UByteArray = ubyteArrayOf()
 | 
				
			||||||
    ): UByteArray
 | 
					    ): UByteArray
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -1,7 +1,7 @@
 | 
				
			|||||||
package com.ionspin.kotlin.crypto.hash.sha
 | 
					package com.ionspin.kotlin.crypto.hash.sha
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import com.ionspin.kotlin.crypto.hash.Hash
 | 
					import com.ionspin.kotlin.crypto.hash.Hash
 | 
				
			||||||
import com.ionspin.kotlin.crypto.hash.MultiPartHash
 | 
					import com.ionspin.kotlin.crypto.hash.MultipartHash
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Created by Ugljesa Jovanovic
 | 
					 * Created by Ugljesa Jovanovic
 | 
				
			||||||
@ -11,15 +11,15 @@ import com.ionspin.kotlin.crypto.hash.MultiPartHash
 | 
				
			|||||||
object Sha512Properties {
 | 
					object Sha512Properties {
 | 
				
			||||||
    const val MAX_HASH_BYTES = 64
 | 
					    const val MAX_HASH_BYTES = 64
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
interface Sha512 : MultiPartHash {
 | 
					interface Sha512 : MultipartHash {
 | 
				
			||||||
    override val MAX_HASH_BYTES: Int
 | 
					    override val MAX_HASH_BYTES: Int
 | 
				
			||||||
        get() = Sha256Properties.MAX_HASH_BYTES
 | 
					        get() = Sha256Properties.MAX_HASH_BYTES
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
interface StatelessSha512 : Hash {
 | 
					interface MultipartSha512 : Hash {
 | 
				
			||||||
    override val MAX_HASH_BYTES: Int
 | 
					    override val MAX_HASH_BYTES: Int
 | 
				
			||||||
        get() = Sha512Properties.MAX_HASH_BYTES
 | 
					        get() = Sha512Properties.MAX_HASH_BYTES
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fun digest(
 | 
					    fun digest(
 | 
				
			||||||
        inputMessage: UByteArray = ubyteArrayOf()
 | 
					        inputMessage: UByteArray = ubyteArrayOf()
 | 
				
			||||||
    ): UByteArray
 | 
					    ): UByteArray
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -23,4 +23,13 @@ package com.ionspin.kotlin.crypto.keyderivation
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
interface KeyDerivationFunction {
 | 
					interface KeyDerivationFunction {
 | 
				
			||||||
    fun derive() : UByteArray
 | 
					    fun derive() : UByteArray
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					data class ArgonResult(
 | 
				
			||||||
 | 
					    val hashBytes: UByteArray,
 | 
				
			||||||
 | 
					    val salt: UByteArray
 | 
				
			||||||
 | 
					) {
 | 
				
			||||||
 | 
					    val hashString by lazy { hashBytes.map { it.toString(16).padStart(2, '0') }.joinToString(separator = "") }
 | 
				
			||||||
 | 
					    val saltString by lazy { salt.map { it.toString(16).padStart(2, '0') }.joinToString(separator = "") }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -3,7 +3,9 @@ package com.ionspin.kotlin.crypto
 | 
				
			|||||||
import com.ionspin.kotlin.crypto.hash.blake2b.Blake2bProperties
 | 
					import com.ionspin.kotlin.crypto.hash.blake2b.Blake2bProperties
 | 
				
			||||||
import com.ionspin.kotlin.crypto.hash.blake2b.Blake2bDelegated
 | 
					import com.ionspin.kotlin.crypto.hash.blake2b.Blake2bDelegated
 | 
				
			||||||
import com.ionspin.kotlin.crypto.hash.blake2b.Blake2bDelegatedStateless
 | 
					import com.ionspin.kotlin.crypto.hash.blake2b.Blake2bDelegatedStateless
 | 
				
			||||||
 | 
					import com.ionspin.kotlin.crypto.hash.blake2b.Blake2bMultipart
 | 
				
			||||||
import com.ionspin.kotlin.crypto.hash.sha.*
 | 
					import com.ionspin.kotlin.crypto.hash.sha.*
 | 
				
			||||||
 | 
					import com.ionspin.kotlin.crypto.keyderivation.ArgonResult
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Created by Ugljesa Jovanovic
 | 
					 * Created by Ugljesa Jovanovic
 | 
				
			||||||
@ -11,18 +13,27 @@ import com.ionspin.kotlin.crypto.hash.sha.*
 | 
				
			|||||||
 * on 24-May-2020
 | 
					 * on 24-May-2020
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
object Crypto : CryptoProvider {
 | 
					object CryptoInitializerDelegated : CryptoInitializer {
 | 
				
			||||||
 | 
					    private var initialized = false
 | 
				
			||||||
    override suspend fun initialize() {
 | 
					    override suspend fun initialize() {
 | 
				
			||||||
        Initializer.initialize()
 | 
					        Initializer.initialize()
 | 
				
			||||||
 | 
					        initialized = true
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fun initializeWithCallback(done: () -> Unit) {
 | 
					    fun initializeWithCallback(done: () -> Unit) {
 | 
				
			||||||
 | 
					        initialized = true
 | 
				
			||||||
        Initializer.initializeWithCallback(done)
 | 
					        Initializer.initializeWithCallback(done)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    override fun isInitialized(): Boolean {
 | 
				
			||||||
 | 
					        return initialized
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					object CryptoPrimitives : PrimitivesApi {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    object Blake2b {
 | 
					    object Blake2b {
 | 
				
			||||||
        fun updateable(key: UByteArray? = null, hashLength: Int = Blake2bProperties.MAX_HASH_BYTES): com.ionspin.kotlin.crypto.hash.blake2b.Blake2b {
 | 
					        fun updateable(key: UByteArray? = null, hashLength: Int = Blake2bProperties.MAX_HASH_BYTES): com.ionspin.kotlin.crypto.hash.blake2b.Blake2bMultipart {
 | 
				
			||||||
            checkInitialization()
 | 
					            checkInitialization()
 | 
				
			||||||
            return Blake2bDelegated(key, hashLength)
 | 
					            return Blake2bDelegated(key, hashLength)
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@ -63,12 +74,135 @@ object Crypto : CryptoProvider {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    override fun hashBlake2bMultipart(key: UByteArray?, hashLength: Int): Blake2bMultipart {
 | 
				
			||||||
 | 
					        checkInitialization()
 | 
				
			||||||
 | 
					        return Blake2bDelegated(key, hashLength)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    override fun hashBlake2b(message: UByteArray, key: UByteArray, hashLength: Int): UByteArray {
 | 
				
			||||||
 | 
					        checkInitialization()
 | 
				
			||||||
 | 
					        return Blake2bDelegatedStateless.digest(message, key, hashLength)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    override fun hashSha256Multipart(): com.ionspin.kotlin.crypto.hash.sha.Sha256 {
 | 
				
			||||||
 | 
					        checkInitialization()
 | 
				
			||||||
 | 
					        return Sha256Delegated()
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    override fun hashSha256(message: UByteArray): UByteArray {
 | 
				
			||||||
 | 
					        checkInitialization()
 | 
				
			||||||
 | 
					        return Sha256StatelessDelegated.digest(inputMessage =  message)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    override fun hashSha512Multipart(): com.ionspin.kotlin.crypto.hash.sha.Sha512 {
 | 
				
			||||||
 | 
					        checkInitialization()
 | 
				
			||||||
 | 
					        return Sha512Delegated()
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    override fun hashSha512(message: UByteArray): UByteArray {
 | 
				
			||||||
 | 
					        checkInitialization()
 | 
				
			||||||
 | 
					        return Sha512StatelessDelegated.digest(inputMessage =  message)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    override fun deriveKey(
 | 
				
			||||||
 | 
					        password: String,
 | 
				
			||||||
 | 
					        salt: String?,
 | 
				
			||||||
 | 
					        key: String,
 | 
				
			||||||
 | 
					        associatedData: String,
 | 
				
			||||||
 | 
					        parallelism: Int,
 | 
				
			||||||
 | 
					        tagLength: Int,
 | 
				
			||||||
 | 
					        memory: Int,
 | 
				
			||||||
 | 
					        numberOfIterations: Int
 | 
				
			||||||
 | 
					    ): ArgonResult {
 | 
				
			||||||
 | 
					//        return Argon2Delegated.derive(
 | 
				
			||||||
 | 
					//            password,
 | 
				
			||||||
 | 
					//            salt,
 | 
				
			||||||
 | 
					//            key,
 | 
				
			||||||
 | 
					//            associatedData,
 | 
				
			||||||
 | 
					//            parallelism,
 | 
				
			||||||
 | 
					//            tagLength,
 | 
				
			||||||
 | 
					//            memory,
 | 
				
			||||||
 | 
					//            numberOfIterations
 | 
				
			||||||
 | 
					//        )
 | 
				
			||||||
 | 
					        TODO()
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
object SimpleCrypto {
 | 
					fun SymmetricKey.Companion.randomKey() : SymmetricKey {
 | 
				
			||||||
    fun hash(message: String): UByteArray {
 | 
					    return SymmetricKey(SRNG.getRandomBytes(32))
 | 
				
			||||||
        return ubyteArrayOf(0U)
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					object Crypto {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    object Hash : HashApi {
 | 
				
			||||||
 | 
					        override fun hash(data: UByteArray, key : UByteArray) : HashedData {
 | 
				
			||||||
 | 
					            return HashedData(Blake2bDelegatedStateless.digest(data, key))
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        override fun multipartHash(key: UByteArray?) : com.ionspin.kotlin.crypto.hash.MultipartHash {
 | 
				
			||||||
 | 
					            return Blake2bDelegated(key)
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    object Encryption : EncryptionApi {
 | 
				
			||||||
 | 
					        override fun encrypt(key: SymmetricKey, data : Encryptable<*>, additionalData : 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)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        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 multipartEncrypt(key: SymmetricKey, additionalData: UByteArray) : MultipartAuthenticatedEncryption {
 | 
				
			||||||
 | 
					            return MultipartAuthenticatedEncryptor(key, additionalData)
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        override fun multipartDecryptProcessStart(key: SymmetricKey, dataDescriptor: MultipartEncryptedDataDescriptor, additionalData: UByteArray) : MultipartAuthenticatedVerification {
 | 
				
			||||||
 | 
					            return MultiplatformAuthenticatedVerificator(key, dataDescriptor, additionalData)
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class MultipartAuthenticatedEncryptor internal constructor(val key : SymmetricKey, additionalData: UByteArray) : MultipartAuthenticatedEncryption {
 | 
				
			||||||
 | 
					    val primitive = XChaCha20Poly1305Pure(key.value, additionalData)
 | 
				
			||||||
 | 
					    override fun encryptPartialData(data: UByteArray): EncryptedDataPart {
 | 
				
			||||||
 | 
					        return EncryptedDataPart(primitive.encryptPartialData(data))
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    override fun finish(): MultipartEncryptedDataDescriptor {
 | 
				
			||||||
 | 
					        val finished = primitive.finish()
 | 
				
			||||||
 | 
					        return MultipartEncryptedDataDescriptor(finished.first, finished.second)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class MultiplatformAuthenticatedVerificator internal constructor(key: SymmetricKey, multipartEncryptedDataDescriptor: MultipartEncryptedDataDescriptor, additionalData: UByteArray) : MultipartAuthenticatedVerification {
 | 
				
			||||||
 | 
					    val primitive = XChaCha20Poly1305Pure(key.value, additionalData)
 | 
				
			||||||
 | 
					    val tag = multipartEncryptedDataDescriptor.data.sliceArray(
 | 
				
			||||||
 | 
					        multipartEncryptedDataDescriptor.data.size - 16 until multipartEncryptedDataDescriptor.data.size
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					    override fun verifyPartialData(data: EncryptedDataPart) {
 | 
				
			||||||
 | 
					        primitive.verifyPartialData(data.data)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    override fun finalizeVerificationAndPrepareDecryptor(): MultipartAuthenticatedDecryption {
 | 
				
			||||||
 | 
					        primitive.checkTag(tag)
 | 
				
			||||||
 | 
					        return MultipartAuthenticatedDecryptor(primitive)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class MultipartAuthenticatedDecryptor internal constructor(val encryptor: XChaCha20Poly1305Pure) : MultipartAuthenticatedDecryption {
 | 
				
			||||||
 | 
					    override fun decryptPartialData(data: EncryptedDataPart): DecryptedDataPart {
 | 
				
			||||||
 | 
					        return DecryptedDataPart(encryptor.decrypt(data.data))
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -23,9 +23,9 @@ package com.ionspin.kotlin.crypto.hash.blake2b
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
expect class Blake2bDelegated(key: UByteArray? = null, hashLength: Int = Blake2bProperties.MAX_HASH_BYTES) : Blake2b
 | 
					expect class Blake2bDelegated(key: UByteArray? = null, hashLength: Int = Blake2bProperties.MAX_HASH_BYTES) : Blake2bMultipart
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
expect object Blake2bDelegatedStateless : Blake2bStateless
 | 
					expect object Blake2bDelegatedStateless : Blake2b
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -26,4 +26,4 @@ package com.ionspin.kotlin.crypto.hash.sha
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
expect class Sha512Delegated() : Sha512
 | 
					expect class Sha512Delegated() : Sha512
 | 
				
			||||||
 | 
					
 | 
				
			||||||
expect object Sha512StatelessDelegated : StatelessSha512
 | 
					expect object Sha512StatelessDelegated : MultipartSha512
 | 
				
			||||||
 | 
				
			|||||||
@ -1,8 +1,6 @@
 | 
				
			|||||||
package com.ionspin.kotlin.crypto.hash.blake2b
 | 
					package com.ionspin.kotlin.crypto.hash.blake2b
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import com.ionspin.kotlin.crypto.getSodium
 | 
					import com.ionspin.kotlin.crypto.getSodium
 | 
				
			||||||
import com.ionspin.kotlin.crypto.hash.sha.Sha256StatelessDelegated
 | 
					 | 
				
			||||||
import com.ionspin.kotlin.crypto.util.toHexString
 | 
					 | 
				
			||||||
import org.khronos.webgl.Uint8Array
 | 
					import org.khronos.webgl.Uint8Array
 | 
				
			||||||
import org.khronos.webgl.get
 | 
					import org.khronos.webgl.get
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -13,7 +11,7 @@ import org.khronos.webgl.get
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
actual class Blake2bDelegated actual constructor(key: UByteArray?, val hashLength: Int) : Blake2b {
 | 
					actual class Blake2bDelegated actual constructor(key: UByteArray?, val hashLength: Int) : Blake2bMultipart {
 | 
				
			||||||
    override val MAX_HASH_BYTES: Int = 64
 | 
					    override val MAX_HASH_BYTES: Int = 64
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -43,7 +41,7 @@ actual class Blake2bDelegated actual constructor(key: UByteArray?, val hashLengt
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
actual object Blake2bDelegatedStateless : Blake2bStateless {
 | 
					actual object Blake2bDelegatedStateless : Blake2b {
 | 
				
			||||||
    override val MAX_HASH_BYTES: Int = 64
 | 
					    override val MAX_HASH_BYTES: Int = 64
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    override fun digest(inputMessage: UByteArray, key: UByteArray, hashLength: Int): UByteArray {
 | 
					    override fun digest(inputMessage: UByteArray, key: UByteArray, hashLength: Int): UByteArray {
 | 
				
			||||||
@ -59,4 +57,4 @@ actual object Blake2bDelegatedStateless : Blake2bStateless {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -1,6 +1,5 @@
 | 
				
			|||||||
package com.ionspin.kotlin.crypto.hash.sha
 | 
					package com.ionspin.kotlin.crypto.hash.sha
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import com.ionspin.kotlin.crypto.getSodium
 | 
					 | 
				
			||||||
import com.ionspin.kotlin.crypto.getSodium
 | 
					import com.ionspin.kotlin.crypto.getSodium
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import org.khronos.webgl.Uint8Array
 | 
					import org.khronos.webgl.Uint8Array
 | 
				
			||||||
@ -35,7 +34,7 @@ actual class Sha512Delegated : Sha512 {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
actual object Sha512StatelessDelegated : StatelessSha512 {
 | 
					actual object Sha512StatelessDelegated : MultipartSha512 {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    override fun digest(inputMessage: UByteArray): UByteArray {
 | 
					    override fun digest(inputMessage: UByteArray): UByteArray {
 | 
				
			||||||
        val hashed = getSodium().crypto_hash_sha512(Uint8Array(inputMessage.toByteArray().toTypedArray()))
 | 
					        val hashed = getSodium().crypto_hash_sha512(Uint8Array(inputMessage.toByteArray().toTypedArray()))
 | 
				
			||||||
@ -45,4 +44,4 @@ actual object Sha512StatelessDelegated : StatelessSha512 {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
        return hash
 | 
					        return hash
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -8,7 +8,7 @@ import com.ionspin.kotlin.crypto.Initializer.sodium
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
actual class Blake2bDelegated actual constructor(key: UByteArray?, val hashLength: Int) : Blake2b {
 | 
					actual class Blake2bDelegated actual constructor(key: UByteArray?, val hashLength: Int) : Blake2bMultipart {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    val state = ByteArray(sodium.crypto_generichash_statebytes())
 | 
					    val state = ByteArray(sodium.crypto_generichash_statebytes())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -28,7 +28,7 @@ actual class Blake2bDelegated actual constructor(key: UByteArray?, val hashLengt
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
actual object Blake2bDelegatedStateless : Blake2bStateless {
 | 
					actual object Blake2bDelegatedStateless : Blake2b {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    override fun digest(inputMessage: UByteArray, key: UByteArray, hashLength: Int): UByteArray {
 | 
					    override fun digest(inputMessage: UByteArray, key: UByteArray, hashLength: Int): UByteArray {
 | 
				
			||||||
@ -37,4 +37,4 @@ actual object Blake2bDelegatedStateless : Blake2bStateless {
 | 
				
			|||||||
        return hashed.toUByteArray()
 | 
					        return hashed.toUByteArray()
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -30,11 +30,11 @@ actual class Sha512Delegated : Sha512 {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
actual object Sha512StatelessDelegated : StatelessSha512 {
 | 
					actual object Sha512StatelessDelegated : MultipartSha512 {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    override fun digest(inputMessage: UByteArray): UByteArray {
 | 
					    override fun digest(inputMessage: UByteArray): UByteArray {
 | 
				
			||||||
        val hashed = ByteArray(Sha512Properties.MAX_HASH_BYTES)
 | 
					        val hashed = ByteArray(Sha512Properties.MAX_HASH_BYTES)
 | 
				
			||||||
        Initializer.sodium.crypto_hash_sha512(hashed, inputMessage.toByteArray(), inputMessage.size.toLong())
 | 
					        Initializer.sodium.crypto_hash_sha512(hashed, inputMessage.toByteArray(), inputMessage.size.toLong())
 | 
				
			||||||
        return hashed.toUByteArray()
 | 
					        return hashed.toUByteArray()
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -0,0 +1,164 @@
 | 
				
			|||||||
 | 
					package com.ionspin.kotlin.crypto
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import com.ionspin.kotlin.crypto.authenticated.*
 | 
				
			||||||
 | 
					import com.ionspin.kotlin.crypto.hash.blake2b.Blake2b
 | 
				
			||||||
 | 
					import com.ionspin.kotlin.crypto.hash.blake2b.Blake2bMultipart
 | 
				
			||||||
 | 
					import com.ionspin.kotlin.crypto.hash.blake2b.Blake2bPure
 | 
				
			||||||
 | 
					import com.ionspin.kotlin.crypto.hash.sha.Sha256Pure
 | 
				
			||||||
 | 
					import com.ionspin.kotlin.crypto.hash.sha.Sha512Pure
 | 
				
			||||||
 | 
					import com.ionspin.kotlin.crypto.keyderivation.ArgonResult
 | 
				
			||||||
 | 
					import com.ionspin.kotlin.crypto.keyderivation.argon2.Argon2Pure
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Created by Ugljesa Jovanovic
 | 
				
			||||||
 | 
					 * ugljesa.jovanovic@ionspin.com
 | 
				
			||||||
 | 
					 * on 24-May-2020
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					object CryptoInitializerPure : CryptoInitializer {
 | 
				
			||||||
 | 
					    override suspend fun initialize() {
 | 
				
			||||||
 | 
					        //Nothing to do atm.
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fun initializeWithCallback(done: () -> Unit) {
 | 
				
			||||||
 | 
					        done()
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    override fun isInitialized(): Boolean {
 | 
				
			||||||
 | 
					        return true
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					object CryptoPrimitives : PrimitivesApi {
 | 
				
			||||||
 | 
					    private fun checkInitialization() {
 | 
				
			||||||
 | 
					        CryptoInitializerPure.isInitialized()
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    override fun hashBlake2bMultipart(key: UByteArray?, hashLength: Int): Blake2bMultipart {
 | 
				
			||||||
 | 
					        checkInitialization()
 | 
				
			||||||
 | 
					        return Blake2bPure(key, hashLength)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    override fun hashBlake2b(message: UByteArray, key: UByteArray, hashLength: Int): UByteArray {
 | 
				
			||||||
 | 
					        checkInitialization()
 | 
				
			||||||
 | 
					        return Blake2bPure.digest(message, key, hashLength)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    override fun hashSha256Multipart(): com.ionspin.kotlin.crypto.hash.sha.Sha256 {
 | 
				
			||||||
 | 
					        checkInitialization()
 | 
				
			||||||
 | 
					        return Sha256Pure()
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    override fun hashSha256(message: UByteArray): UByteArray {
 | 
				
			||||||
 | 
					        checkInitialization()
 | 
				
			||||||
 | 
					        return Sha256Pure.digest(inputMessage =  message)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    override fun hashSha512Multipart(): com.ionspin.kotlin.crypto.hash.sha.Sha512 {
 | 
				
			||||||
 | 
					        checkInitialization()
 | 
				
			||||||
 | 
					        return Sha512Pure()
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    override fun hashSha512(message: UByteArray): UByteArray {
 | 
				
			||||||
 | 
					        checkInitialization()
 | 
				
			||||||
 | 
					        return Sha512Pure.digest(inputMessage =  message)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    override fun deriveKey(
 | 
				
			||||||
 | 
					        password: String,
 | 
				
			||||||
 | 
					        salt: String?,
 | 
				
			||||||
 | 
					        key: String,
 | 
				
			||||||
 | 
					        associatedData: String,
 | 
				
			||||||
 | 
					        parallelism: Int,
 | 
				
			||||||
 | 
					        tagLength: Int,
 | 
				
			||||||
 | 
					        memory: Int,
 | 
				
			||||||
 | 
					        numberOfIterations: Int
 | 
				
			||||||
 | 
					    ): ArgonResult {
 | 
				
			||||||
 | 
					        return Argon2Pure.derive(
 | 
				
			||||||
 | 
					            password,
 | 
				
			||||||
 | 
					            salt,
 | 
				
			||||||
 | 
					            key,
 | 
				
			||||||
 | 
					            associatedData,
 | 
				
			||||||
 | 
					            parallelism,
 | 
				
			||||||
 | 
					            tagLength,
 | 
				
			||||||
 | 
					            memory,
 | 
				
			||||||
 | 
					            numberOfIterations
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fun SymmetricKey.Companion.randomKey() : SymmetricKey {
 | 
				
			||||||
 | 
					    return SymmetricKey(SRNG.getRandomBytes(32))
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					object Crypto {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    object Hash : HashApi {
 | 
				
			||||||
 | 
					        override fun hash(data: UByteArray, key : UByteArray) : HashedData {
 | 
				
			||||||
 | 
					            return HashedData(Blake2bPure.digest(data, key))
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        override fun multipartHash(key: UByteArray?) : com.ionspin.kotlin.crypto.hash.MultipartHash {
 | 
				
			||||||
 | 
					            return Blake2bPure(key)
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    object Encryption : EncryptionApi {
 | 
				
			||||||
 | 
					        override fun encrypt(key: SymmetricKey, data : Encryptable<*>, additionalData : 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)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        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 multipartEncrypt(key: SymmetricKey, additionalData: UByteArray) : MultipartAuthenticatedEncryption {
 | 
				
			||||||
 | 
					            return MultipartAuthenticatedEncryptor(key, additionalData)
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        override fun multipartDecryptProcessStart(key: SymmetricKey, dataDescriptor: MultipartEncryptedDataDescriptor, additionalData: UByteArray) : MultipartAuthenticatedVerification {
 | 
				
			||||||
 | 
					            return MultiplatformAuthenticatedVerificator(key, dataDescriptor, additionalData)
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class MultipartAuthenticatedEncryptor internal constructor(val key : SymmetricKey, additionalData: UByteArray) : MultipartAuthenticatedEncryption {
 | 
				
			||||||
 | 
					    val primitive = XChaCha20Poly1305Pure(key.value, additionalData)
 | 
				
			||||||
 | 
					    override fun encryptPartialData(data: UByteArray): EncryptedDataPart {
 | 
				
			||||||
 | 
					        return EncryptedDataPart(primitive.encryptPartialData(data))
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    override fun finish(): MultipartEncryptedDataDescriptor {
 | 
				
			||||||
 | 
					        val finished = primitive.finish()
 | 
				
			||||||
 | 
					        return MultipartEncryptedDataDescriptor(finished.first, finished.second)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class MultiplatformAuthenticatedVerificator internal constructor(key: SymmetricKey, multipartEncryptedDataDescriptor: MultipartEncryptedDataDescriptor, additionalData: UByteArray) : MultipartAuthenticatedVerification {
 | 
				
			||||||
 | 
					    val primitive = XChaCha20Poly1305Pure(key.value, additionalData)
 | 
				
			||||||
 | 
					    val tag = multipartEncryptedDataDescriptor.data.sliceArray(
 | 
				
			||||||
 | 
					        multipartEncryptedDataDescriptor.data.size - 16 until multipartEncryptedDataDescriptor.data.size
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					    override fun verifyPartialData(data: EncryptedDataPart) {
 | 
				
			||||||
 | 
					        primitive.verifyPartialData(data.data)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    override fun finalizeVerificationAndPrepareDecryptor(): MultipartAuthenticatedDecryption {
 | 
				
			||||||
 | 
					        primitive.checkTag(tag)
 | 
				
			||||||
 | 
					        return MultipartAuthenticatedDecryptor(primitive)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class MultipartAuthenticatedDecryptor internal constructor(val encryptor: XChaCha20Poly1305Pure) : MultipartAuthenticatedDecryption {
 | 
				
			||||||
 | 
					    override fun decryptPartialData(data: EncryptedDataPart): DecryptedDataPart {
 | 
				
			||||||
 | 
					        return DecryptedDataPart(encryptor.decrypt(data.data))
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -1,185 +0,0 @@
 | 
				
			|||||||
package com.ionspin.kotlin.crypto
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import com.ionspin.kotlin.crypto.authenticated.*
 | 
					 | 
				
			||||||
import com.ionspin.kotlin.crypto.hash.blake2b.Blake2bProperties
 | 
					 | 
				
			||||||
import com.ionspin.kotlin.crypto.hash.blake2b.Blake2bPure
 | 
					 | 
				
			||||||
import com.ionspin.kotlin.crypto.hash.encodeToUByteArray
 | 
					 | 
				
			||||||
import com.ionspin.kotlin.crypto.hash.sha.Sha256Pure
 | 
					 | 
				
			||||||
import com.ionspin.kotlin.crypto.hash.sha.Sha512Pure
 | 
					 | 
				
			||||||
import com.ionspin.kotlin.crypto.util.toHexString
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Created by Ugljesa Jovanovic
 | 
					 | 
				
			||||||
 * ugljesa.jovanovic@ionspin.com
 | 
					 | 
				
			||||||
 * on 24-May-2020
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
typealias Blake2bPureStateless = Blake2bPure.Companion
 | 
					 | 
				
			||||||
typealias Sha256PureStateless = Sha256Pure.Companion
 | 
					 | 
				
			||||||
typealias Sha512PureStateless = Sha512Pure.Companion
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
object Primitives : CryptoProvider {
 | 
					 | 
				
			||||||
    override suspend fun initialize() {
 | 
					 | 
				
			||||||
        //Nothing to do atm.
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    fun initializeWithCallback(done: () -> Unit) {
 | 
					 | 
				
			||||||
        done()
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    object Blake2b {
 | 
					 | 
				
			||||||
        fun updateable(key: UByteArray? = null, hashLength: Int = Blake2bProperties.MAX_HASH_BYTES): com.ionspin.kotlin.crypto.hash.blake2b.Blake2b {
 | 
					 | 
				
			||||||
            checkInitialization()
 | 
					 | 
				
			||||||
            return Blake2bPure(key, hashLength)
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        fun stateless(message: UByteArray, key: UByteArray = ubyteArrayOf(), hashLength: Int = Blake2bProperties.MAX_HASH_BYTES): UByteArray {
 | 
					 | 
				
			||||||
            checkInitialization()
 | 
					 | 
				
			||||||
            return Blake2bPureStateless.digest(message, key, hashLength)
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    object Sha256 {
 | 
					 | 
				
			||||||
        fun updateable(): com.ionspin.kotlin.crypto.hash.sha.Sha256 {
 | 
					 | 
				
			||||||
            checkInitialization()
 | 
					 | 
				
			||||||
            return Sha256Pure()
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        fun stateless(message: UByteArray) : UByteArray{
 | 
					 | 
				
			||||||
            checkInitialization()
 | 
					 | 
				
			||||||
            return Sha256PureStateless.digest(inputMessage =  message)
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    object Sha512 {
 | 
					 | 
				
			||||||
        fun updateable(): com.ionspin.kotlin.crypto.hash.sha.Sha512 {
 | 
					 | 
				
			||||||
            checkInitialization()
 | 
					 | 
				
			||||||
            return Sha512Pure()
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        fun stateless(message: UByteArray) : UByteArray {
 | 
					 | 
				
			||||||
            checkInitialization()
 | 
					 | 
				
			||||||
            return Sha512PureStateless.digest(inputMessage =  message)
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    private fun checkInitialization() {
 | 
					 | 
				
			||||||
        // Nothing to do atm
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
inline class EncryptableString(val content: String) : Encryptable<EncryptableString> {
 | 
					 | 
				
			||||||
    override fun toEncryptableForm(): UByteArray {
 | 
					 | 
				
			||||||
        return content.encodeToUByteArray()
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    override fun fromEncryptableForm(): (UByteArray) -> EncryptableString {
 | 
					 | 
				
			||||||
        return { uByteArray ->
 | 
					 | 
				
			||||||
            EncryptableString(uByteArray.toByteArray().decodeToString())
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    fun asString() : String = content
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
fun String.asEncryptableString() : EncryptableString {
 | 
					 | 
				
			||||||
    return EncryptableString(this)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
interface Encryptable<T> {
 | 
					 | 
				
			||||||
    fun toEncryptableForm() : UByteArray
 | 
					 | 
				
			||||||
    fun fromEncryptableForm() : (UByteArray) -> T
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
data class HashedData(val hash: UByteArray) {
 | 
					 | 
				
			||||||
    fun toHexString() : String {
 | 
					 | 
				
			||||||
        return hash.toHexString()
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
data class SymmetricKey(val value : UByteArray) {
 | 
					 | 
				
			||||||
    companion object {
 | 
					 | 
				
			||||||
        fun randomKey() : SymmetricKey {
 | 
					 | 
				
			||||||
            return SymmetricKey(SRNG.getRandomBytes(32))
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
data class EncryptedData internal constructor(val ciphertext: UByteArray, val nonce: UByteArray) {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
object PublicApi {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    object Hashing {
 | 
					 | 
				
			||||||
        fun hash(data: UByteArray, key : UByteArray = ubyteArrayOf()) : HashedData {
 | 
					 | 
				
			||||||
            return HashedData(Blake2bPureStateless.digest(data, key))
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        fun multipartHash(key: UByteArray? = null) : com.ionspin.kotlin.crypto.hash.MultiPartHash {
 | 
					 | 
				
			||||||
            return Blake2bPure(key)
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    object Encryption {
 | 
					 | 
				
			||||||
        fun authenticatedEncryption(key: SymmetricKey, data : Encryptable<*>, additionalData : UByteArray = ubyteArrayOf()) : 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)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        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))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        fun multipartAuthenticatedEncrypt(key: SymmetricKey, additionalData: UByteArray) : MultipartAuthenticatedEncryption {
 | 
					 | 
				
			||||||
            return MultipartAuthenticatedEncryptor(key, additionalData)
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        fun getMultipartVerificator(key: SymmetricKey, dataDescriptor: MultipartEncryptedDataDescriptor, additionalData: UByteArray) : MultipartAuthenticatedVerification {
 | 
					 | 
				
			||||||
            return MultiplatformAuthenticatedVerificator(key, dataDescriptor, additionalData)
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class MultipartAuthenticatedEncryptor internal constructor(val key : SymmetricKey, additionalData: UByteArray) : MultipartAuthenticatedEncryption {
 | 
					 | 
				
			||||||
    val primitive = XChaCha20Poly1305Pure(key.value, additionalData)
 | 
					 | 
				
			||||||
    override fun encryptPartialData(data: UByteArray): EncryptedDataPart {
 | 
					 | 
				
			||||||
        return EncryptedDataPart(primitive.encryptPartialData(data))
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    override fun finish(): MultipartEncryptedDataDescriptor {
 | 
					 | 
				
			||||||
        val finished = primitive.finish()
 | 
					 | 
				
			||||||
        return MultipartEncryptedDataDescriptor(finished.first, finished.second)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class MultiplatformAuthenticatedVerificator internal constructor(key: SymmetricKey, multipartEncryptedDataDescriptor: MultipartEncryptedDataDescriptor, additionalData: UByteArray) : MultipartAuthenticatedVerification {
 | 
					 | 
				
			||||||
    val primitive = XChaCha20Poly1305Pure(key.value, additionalData)
 | 
					 | 
				
			||||||
    val tag = multipartEncryptedDataDescriptor.data.sliceArray(
 | 
					 | 
				
			||||||
        multipartEncryptedDataDescriptor.data.size - 16 until multipartEncryptedDataDescriptor.data.size
 | 
					 | 
				
			||||||
    )
 | 
					 | 
				
			||||||
    override fun verifyPartialData(data: EncryptedDataPart) {
 | 
					 | 
				
			||||||
        primitive.encryptPartialData(data.data)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    override fun finalizeVerificationAndPrepareDecryptor(): MultipartAuthenticatedDecryption {
 | 
					 | 
				
			||||||
        primitive.finalizeVerificationAndPrepareDecryptor(tag)
 | 
					 | 
				
			||||||
        return MultipartAuthenticatedDecryptor(primitive)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class MultipartAuthenticatedDecryptor internal constructor(val encryptor: XChaCha20Poly1305Pure) : MultipartAuthenticatedDecryption {
 | 
					 | 
				
			||||||
    override fun decryptPartialData(data: EncryptedDataPart): DecryptedDataPart {
 | 
					 | 
				
			||||||
        encryptor.decrypt(data.data)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,5 +1,7 @@
 | 
				
			|||||||
package com.ionspin.kotlin.crypto.authenticated
 | 
					package com.ionspin.kotlin.crypto.authenticated
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import com.ionspin.kotlin.crypto.InvalidTagException
 | 
				
			||||||
 | 
					import com.ionspin.kotlin.crypto.MultipartAuthenticatedDecryption
 | 
				
			||||||
import com.ionspin.kotlin.crypto.SRNG
 | 
					import com.ionspin.kotlin.crypto.SRNG
 | 
				
			||||||
import com.ionspin.kotlin.crypto.mac.Poly1305
 | 
					import com.ionspin.kotlin.crypto.mac.Poly1305
 | 
				
			||||||
import com.ionspin.kotlin.crypto.symmetric.ChaCha20Pure
 | 
					import com.ionspin.kotlin.crypto.symmetric.ChaCha20Pure
 | 
				
			||||||
@ -58,7 +60,7 @@ class XChaCha20Poly1305Pure(val key: UByteArray, val additionalData: UByteArray)
 | 
				
			|||||||
                    cipherTextWithoutTag.size.toULong().toLittleEndianUByteArray()
 | 
					                    cipherTextWithoutTag.size.toULong().toLittleEndianUByteArray()
 | 
				
			||||||
            val calculatedTag = Poly1305.poly1305Authenticate(authKey, macData)
 | 
					            val calculatedTag = Poly1305.poly1305Authenticate(authKey, macData)
 | 
				
			||||||
            if (!calculatedTag.contentEquals(tag)) {
 | 
					            if (!calculatedTag.contentEquals(tag)) {
 | 
				
			||||||
                RuntimeException("Bad tag!") //TODO replace with specific exception
 | 
					                throw InvalidTagException()
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            //4. Decrypt data
 | 
					            //4. Decrypt data
 | 
				
			||||||
            return XChaCha20Pure.xorWithKeystream(key, nonce, cipherTextWithoutTag, 1U)
 | 
					            return XChaCha20Pure.xorWithKeystream(key, nonce, cipherTextWithoutTag, 1U)
 | 
				
			||||||
@ -106,7 +108,7 @@ class XChaCha20Poly1305Pure(val key: UByteArray, val additionalData: UByteArray)
 | 
				
			|||||||
        processPolyBytes(data)
 | 
					        processPolyBytes(data)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fun finalizeVerificationAndPrepareDecryptor(expectedTag: UByteArray): MultipartAuthenticatedDecryption {
 | 
					    fun checkTag(expectedTag: UByteArray) {
 | 
				
			||||||
        val cipherTextPad = UByteArray(16 - processedBytes % 16) { 0U }
 | 
					        val cipherTextPad = UByteArray(16 - processedBytes % 16) { 0U }
 | 
				
			||||||
        val macData = cipherTextPad +
 | 
					        val macData = cipherTextPad +
 | 
				
			||||||
                additionalData.size.toULong().toLittleEndianUByteArray() +
 | 
					                additionalData.size.toULong().toLittleEndianUByteArray() +
 | 
				
			||||||
@ -114,7 +116,7 @@ class XChaCha20Poly1305Pure(val key: UByteArray, val additionalData: UByteArray)
 | 
				
			|||||||
        processPolyBytes(macData)
 | 
					        processPolyBytes(macData)
 | 
				
			||||||
        val tag = updateableMacPrimitive.finalizeMac()
 | 
					        val tag = updateableMacPrimitive.finalizeMac()
 | 
				
			||||||
        if (!tag.contentEquals(expectedTag)) {
 | 
					        if (!tag.contentEquals(expectedTag)) {
 | 
				
			||||||
            throw RuntimeException("Invalid tag") //TODO Replace with proper exception
 | 
					            throw InvalidTagException()
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -28,9 +28,9 @@ import com.ionspin.kotlin.crypto.util.rotateRight
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Blake2bPure(val key: UByteArray? = null, val hashLength: Int = 64) : Blake2b {
 | 
					class Blake2bPure(val key: UByteArray? = null, val hashLength: Int = 64) : Blake2bMultipart {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    companion object : Blake2bStateless {
 | 
					    companion object : Blake2b {
 | 
				
			||||||
        //Hack start
 | 
					        //Hack start
 | 
				
			||||||
        //If this line is not included konanc 1.4-M1 fails to link because it cant find ByteArray which is
 | 
					        //If this line is not included konanc 1.4-M1 fails to link because it cant find ByteArray which is
 | 
				
			||||||
        //a backing class for UByteArray
 | 
					        //a backing class for UByteArray
 | 
				
			||||||
 | 
				
			|||||||
@ -29,7 +29,7 @@ class Sha512Pure : Sha512 {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    override val MAX_HASH_BYTES: Int = 32
 | 
					    override val MAX_HASH_BYTES: Int = 32
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    companion object : StatelessSha512 {
 | 
					    companion object : MultipartSha512 {
 | 
				
			||||||
        const val BLOCK_SIZE = 1024
 | 
					        const val BLOCK_SIZE = 1024
 | 
				
			||||||
        const val BLOCK_SIZE_IN_BYTES = 128
 | 
					        const val BLOCK_SIZE_IN_BYTES = 128
 | 
				
			||||||
        const val CHUNK_SIZE = 80
 | 
					        const val CHUNK_SIZE = 80
 | 
				
			||||||
@ -385,4 +385,4 @@ class Sha512Pure : Sha512 {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -21,6 +21,7 @@ package com.ionspin.kotlin.crypto.keyderivation.argon2
 | 
				
			|||||||
import com.ionspin.kotlin.bignum.integer.toBigInteger
 | 
					import com.ionspin.kotlin.bignum.integer.toBigInteger
 | 
				
			||||||
import com.ionspin.kotlin.crypto.Blake2bPureStateless
 | 
					import com.ionspin.kotlin.crypto.Blake2bPureStateless
 | 
				
			||||||
import com.ionspin.kotlin.crypto.SRNG
 | 
					import com.ionspin.kotlin.crypto.SRNG
 | 
				
			||||||
 | 
					import com.ionspin.kotlin.crypto.keyderivation.ArgonResult
 | 
				
			||||||
import com.ionspin.kotlin.crypto.keyderivation.argon2.Argon2Utils.argonBlake2bArbitraryLenghtHash
 | 
					import com.ionspin.kotlin.crypto.keyderivation.argon2.Argon2Utils.argonBlake2bArbitraryLenghtHash
 | 
				
			||||||
import com.ionspin.kotlin.crypto.keyderivation.argon2.Argon2Utils.compressionFunctionG
 | 
					import com.ionspin.kotlin.crypto.keyderivation.argon2.Argon2Utils.compressionFunctionG
 | 
				
			||||||
import com.ionspin.kotlin.crypto.keyderivation.argon2.Argon2Utils.validateArgonParameters
 | 
					import com.ionspin.kotlin.crypto.keyderivation.argon2.Argon2Utils.validateArgonParameters
 | 
				
			||||||
@ -42,14 +43,7 @@ data class SegmentPosition(
 | 
				
			|||||||
    val slice: Int
 | 
					    val slice: Int
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
data class ArgonResult(
 | 
					 | 
				
			||||||
    val hashBytes: UByteArray,
 | 
					 | 
				
			||||||
    val salt: UByteArray
 | 
					 | 
				
			||||||
) {
 | 
					 | 
				
			||||||
    val hashString by lazy { hashBytes.map { it.toString(16).padStart(2, '0') }.joinToString(separator = "") }
 | 
					 | 
				
			||||||
    val saltString by lazy { salt.map { it.toString(16).padStart(2, '0') }.joinToString(separator = "") }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -1,12 +1,8 @@
 | 
				
			|||||||
package com.ionspin.kotlin.crypto.sample
 | 
					package com.ionspin.kotlin.crypto.sample
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import com.ionspin.kotlin.crypto.Crypto
 | 
					import com.ionspin.kotlin.crypto.Crypto
 | 
				
			||||||
import com.ionspin.kotlin.crypto.CryptoProvider
 | 
					 | 
				
			||||||
import com.ionspin.kotlin.crypto.hash.blake2b.Blake2b
 | 
					 | 
				
			||||||
import com.ionspin.kotlin.crypto.hash.encodeToUByteArray
 | 
					import com.ionspin.kotlin.crypto.hash.encodeToUByteArray
 | 
				
			||||||
import com.ionspin.kotlin.crypto.util.toHexString
 | 
					import com.ionspin.kotlin.crypto.util.toHexString
 | 
				
			||||||
import kotlinx.coroutines.GlobalScope
 | 
					 | 
				
			||||||
import kotlinx.coroutines.launch
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
object Sample {
 | 
					object Sample {
 | 
				
			||||||
    fun runSample() {
 | 
					    fun runSample() {
 | 
				
			||||||
@ -27,4 +23,4 @@ object Sample {
 | 
				
			|||||||
        val statelessResult = Crypto.Blake2b.stateless("test".encodeToByteArray().toUByteArray())
 | 
					        val statelessResult = Crypto.Blake2b.stateless("test".encodeToByteArray().toUByteArray())
 | 
				
			||||||
        println("Blake2b stateless: ${statelessResult.toHexString()}")
 | 
					        println("Blake2b stateless: ${statelessResult.toHexString()}")
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user