From b0c6b43f2e6377ee99e575b98758999ba87c7089 Mon Sep 17 00:00:00 2001 From: Ugljesa Jovanovic Date: Sat, 9 Jan 2021 12:57:04 +0100 Subject: [PATCH] Add generic hash docs --- .../com.ionspin.kotlin.crypto/aead/Aead.md | 4 ++-- .../com.ionspin.kotlin.crypto/box/Box.md | 8 ++++--- .../generichash/GenericHash.kt | 24 +++++++++++++++++-- .../generichash/GenericHash.md | 19 ++++++++++++++- 4 files changed, 47 insertions(+), 8 deletions(-) diff --git a/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/aead/Aead.md b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/aead/Aead.md index b216ec6..fea6376 100644 --- a/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/aead/Aead.md +++ b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/aead/Aead.md @@ -5,7 +5,7 @@ This is a form of symmetric encryption, that assures both confidentiality and authenticity of the data to be encrypted as well as associated data that will not be encrypted. -In general it works like this: +In general, it works like this: Inputs: - Message to encrypt and authenticate @@ -14,7 +14,7 @@ Inputs: - Additional data that is not encrypted but also authenticated Simplified encryption algorithm: -1. Encrypt message with key and nonce +1. Encrypt a message with key and nonce 1. Apply MAC algorithm to encrypted message + unencrypted associated data to generate authentication data (tag) 1. Send the encrypted data + associated data + authentication data + nonce diff --git a/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/box/Box.md b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/box/Box.md index 30372b0..035c9d3 100644 --- a/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/box/Box.md +++ b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/box/Box.md @@ -5,14 +5,16 @@ Public key encryption is a system that relies on a pair of keys to establish secure communication. A simplified overview of communication between Bob and Alice using public-key encryption: -- Key exchange +#### Key exchange 1. Alice creates 2 keys, one public, one private (public key is actually calculated from the private key) 1. Bob creates 2 keys, one public, one private 1. Alice sends her **public** key to Bob 1. Bob does the same and sends his **public** key to Alice -- Encryption -Alice wants to establish a secure communication channel with Bob, they already changed public keys in previous steps. +#### Encryption + +Alice wants to establish a secure communication channel with Bob, they already exchanged public keys in previous steps. + 1. Alice uses Bobs **private** key to encrypt a *secret value* (Usually just a key for symmetric encryption) 1. Alice sends encrypted data to Bob 1. Bob is the only one who has the matching private key, and can decrypt the data diff --git a/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/generichash/GenericHash.kt b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/generichash/GenericHash.kt index c778647..4c5a829 100644 --- a/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/generichash/GenericHash.kt +++ b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/generichash/GenericHash.kt @@ -21,14 +21,34 @@ data class GenericHashState(val hashLength: Int, val internalState: GenericHashS expect object GenericHash { + /** + * Request computing a hash of message, with a specific hash length and optional key. The specific hash length can be + * between [crypto_generichash_blake2b_BYTES_MIN] and [crypto_generichash_blake2b_BYTES_MAX]. If the key is provided + * it needs the hash will be different for each different key. + */ + fun genericHash(message : UByteArray, requestedHashLength: Int = crypto_generichash_BYTES, key : UByteArray? = null) : UByteArray - fun genericHash(message : UByteArray, requestedHashLength: Int, key : UByteArray? = null) : UByteArray + /** + * Prepare a Generic Hash State object that will be used to compute hash of data with arbitrary length. Secific hash length + * can be requested + */ + fun genericHashInit(requestedHashLength: Int = crypto_generichash_BYTES, key : UByteArray? = null) : GenericHashState - fun genericHashInit(requestedHashLength: Int, key : UByteArray? = null) : GenericHashState + /** + * Feed another chunk of message to the updateable hash object + */ fun genericHashUpdate(state: GenericHashState, messagePart : UByteArray) + + /** + * Feed the last chunk of message to the updateable hash object. This returns the actual hash. + */ fun genericHashFinal(state : GenericHashState) : UByteArray + /** + * Generate a key of length [crypto_generichash_blake2b_KEYBYTES] that can be used with the generic hash funciton + */ fun genericHashKeygen() : UByteArray + // ---- Not present in LazySodium nor libsodium.js // fun blake2b(message : UByteArray, requestedHashLength: Int, key : UByteArray? = null) : UByteArray // diff --git a/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/generichash/GenericHash.md b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/generichash/GenericHash.md index 99420aa..091c997 100644 --- a/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/generichash/GenericHash.md +++ b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/generichash/GenericHash.md @@ -2,5 +2,22 @@ ## Generic hash -Generic hash package provides a easy to use +Generic hash package provides a easy to use hashing API that computes fixed-length fingerprint for an arbitrary long message. +In this case hashing is a process of mapping a set of input bytes to a fixed length (32 bytes) output. Loosely speaking +hash function should be practically irreversible and resistant to collisions (a case where two different inputs result in a same output) + +Some examples of hash function usage: +- Verifying data integrity, i.e. downloading a file and it's hash and then recalculating the hash of the downloaded +file to verify that it hasn't changed +- Creating unique identifiers to index long data +- Password verification, i.e. server stores just the hash of the users password and then when user wants to log in, they send +the password, which server then hashes and compares to the stored hash. This way in case of breach of server security cleartext +passwords are not revealed. With that said **DONT USE GENERIC HASH FOR PASSWORD HASHING**. Use PasswordHash funcitons. + +Underneath this set of functions uses BLAKE2b secure hash function, Here is what Libsodium documentation says about it +>The crypto_generichash_* function set is implemented using BLAKE2b, a simple, standardized (RFC 7693) secure hash +>function that is as strong as SHA-3 but faster than SHA-1 and MD5. +>Unlike MD5, SHA-1 and SHA-256, this function is safe against hash length extension attacks. +>BLAKE2b is not suitable for hashing passwords. For this purpose, use the crypto_pwhash API documented +>in the Password Hashing section.