0.5.4: compound hash
This commit is contained in:
parent
a947271c3c
commit
d0fa74e089
1
.idea/inspectionProfiles/Project_Default.xml
generated
1
.idea/inspectionProfiles/Project_Default.xml
generated
@ -2,5 +2,6 @@
|
||||
<profile version="1.0">
|
||||
<option name="myName" value="Project Default" />
|
||||
<inspection_tool class="ReplaceUntilWithRangeUntil" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
|
||||
<inspection_tool class="StructuralWrap" enabled="false" level="TYPO" enabled_by_default="false" />
|
||||
</profile>
|
||||
</component>
|
12
README.md
12
README.md
@ -9,7 +9,7 @@ All primitives meant to send over the network or store are `kotlinx.serializatio
|
||||
# Important notes on upgrade
|
||||
|
||||
Since version __0.5.*__ key identity calculation for asymmetric keys is updated
|
||||
to make it more safe for theoretic future attack on blake2b hashing. Key.id values
|
||||
to make it safer for theoretic future attack on blake2b hashing. Key.id values
|
||||
are incompatible with older. Sorry for inconvenience.
|
||||
|
||||
# Usage
|
||||
@ -19,7 +19,7 @@ repositories {
|
||||
maven("https://gitea.sergeych.net/api/packages/SergeychWorks/maven")
|
||||
}
|
||||
dependencies {
|
||||
import("net.sergeych:crypto2:0.5.4")
|
||||
import("net.sergeych:crypto2:0.5.5")
|
||||
}
|
||||
```
|
||||
|
||||
@ -59,13 +59,13 @@ Please see the current documentation [here](https://code.sergeych.net/docs/crypt
|
||||
|
||||
## Diffie-Hellman safe key exchange
|
||||
|
||||
Using X25519 curves, generates two symmetric keys with XSalsa20+Poly1305 for independent p2p ciphers and session token, same on both sides.
|
||||
Using X25519 curves, it generates two symmetric keys with XSalsa20+Poly1305 for independent p2p ciphers and session token, same on both sides.
|
||||
|
||||
## Multi-signed container
|
||||
|
||||
A container with random binary or `kolinx.serialized` data, signed with one or more Ed25519 secret keys. Signatures could be added sequentially, each signature contains timestamp and the optional expiration. __Blake2b__ fast and strong hashing is used.
|
||||
|
||||
Signatures include public keys (as these are short for Ed25519) which can be used to identity signing party easily.
|
||||
Signatures include public keys (as these are short for Ed25519) which can be used to easily identify the signing party.
|
||||
|
||||
## Multi-key encrypted contained.
|
||||
|
||||
@ -75,9 +75,9 @@ The `koltlinx.serialized` message intended to be readable by owner of one of an
|
||||
- Secret/Public keys Ed25519.
|
||||
- password-derived keys (PBKDF generation parameters are stored in the container so the key could be derived from the password)
|
||||
|
||||
Once the container is decrypted with any of the intended keys, it could be re-encrypted with new data and/or new destination keys, keeping all existing keys event not having them. E.g., it allows "reply all" function even when not all recipients are known and even if the symmetric key cryptography is used.
|
||||
Once the container is decrypted with any of the intended keys, it could be re-encrypted with new data and/or new destination keys, keeping all existing keys events not having them. E.g., it allows "reply all" function even when not all recipients are known and even if the symmetric key cryptography is used.
|
||||
|
||||
The proper keys are retrieved from the keyrings (below) automatically.
|
||||
The proper keys are retrieved from the keyring (below) automatically.
|
||||
|
||||
## Keyring
|
||||
|
||||
|
@ -6,7 +6,7 @@ plugins {
|
||||
}
|
||||
|
||||
group = "net.sergeych"
|
||||
version = "0.5.4"
|
||||
version = "0.5.5"
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
@ -48,7 +48,7 @@ kotlin {
|
||||
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.7.0")
|
||||
|
||||
implementation("com.ionspin.kotlin:multiplatform-crypto-libsodium-bindings:0.9.2")
|
||||
implementation(platform("org.kotlincrypto.hash:bom:0.5.1"))
|
||||
implementation(project.dependencies.platform("org.kotlincrypto.hash:bom:0.5.1"))
|
||||
implementation("org.kotlincrypto.hash:sha3")
|
||||
api("com.ionspin.kotlin:bignum:0.3.9")
|
||||
api("net.sergeych:mp_bintools:0.1.7")
|
||||
|
@ -21,7 +21,10 @@ private interface StreamProcessor {
|
||||
* - [ofFlow] to calculate hash of the data in the [Flow<UByteArray>]
|
||||
*/
|
||||
@Suppress("unused")
|
||||
enum class Hash(private val direct: ((UByteArray) -> UByteArray)? = null,private val streamProcessor: () -> StreamProcessor) {
|
||||
enum class Hash(
|
||||
private val direct: ((UByteArray) -> UByteArray)? = null,
|
||||
private val streamProcessor: () -> StreamProcessor,
|
||||
) {
|
||||
|
||||
Blake2b(
|
||||
// direct blacke2 is faster than stream:
|
||||
@ -59,6 +62,24 @@ enum class Hash(private val direct: ((UByteArray) -> UByteArray)? = null,private
|
||||
|
||||
override fun final(): UByteArray = state.digest().asUByteArray()
|
||||
}
|
||||
}),
|
||||
|
||||
/**
|
||||
* Synthetic hash contains of [Blake2b] and [Sha3_384] hashes concatenated in this order. Let calculate
|
||||
* compound hash using [ofFlow] or [ofChannel] effectively.
|
||||
*/
|
||||
Sha3AndBlake(null,
|
||||
{
|
||||
object : StreamProcessor {
|
||||
val blake = Blake2b.streamProcessor()
|
||||
val sha384 = Sha3_384.streamProcessor()
|
||||
override fun update(data: UByteArray) {
|
||||
blake.update(data)
|
||||
sha384.update(data)
|
||||
}
|
||||
|
||||
override fun final(): UByteArray = blake.final() + sha384.final()
|
||||
}
|
||||
});
|
||||
|
||||
@Deprecated("will be removed in favor of digest()", ReplaceWith("digest()"))
|
||||
@ -69,7 +90,7 @@ enum class Hash(private val direct: ((UByteArray) -> UByteArray)? = null,private
|
||||
* @param src data to calculate hash digest over
|
||||
* @return calculated hash value
|
||||
*/
|
||||
fun digest(src: UByteArray): UByteArray = direct?.invoke(src) ?: streamProcessor().also { it.update(src)}.final()
|
||||
fun digest(src: UByteArray): UByteArray = direct?.invoke(src) ?: streamProcessor().also { it.update(src) }.final()
|
||||
|
||||
/**
|
||||
* Collect the flow and return the hash digest of all the data. Let calculate hashes on data
|
||||
@ -87,7 +108,7 @@ enum class Hash(private val direct: ((UByteArray) -> UByteArray)? = null,private
|
||||
*/
|
||||
suspend fun ofChannel(source: ReceiveChannel<UByteArray>): UByteArray {
|
||||
val sp = streamProcessor()
|
||||
for( block in source) sp.update(block)
|
||||
for (block in source) sp.update(block)
|
||||
return sp.final()
|
||||
}
|
||||
|
||||
@ -106,7 +127,7 @@ fun blake2b(src: UByteArray): UByteArray = Hash.Blake2b.digest(src)
|
||||
* brute force.collision attack than just [blake2b]. Note that different suffixes provide different
|
||||
* results.
|
||||
*/
|
||||
fun blake2b2l(src: UByteArray,suffix: UByteArray = defaultSuffix1): UByteArray =
|
||||
fun blake2b2l(src: UByteArray, suffix: UByteArray = defaultSuffix1): UByteArray =
|
||||
blake2b(blake2b(src) + suffix + src)
|
||||
|
||||
/**
|
||||
|
@ -35,4 +35,16 @@ class HashTest {
|
||||
testMethod(Hash.Sha3_384)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testSynthetic() = runTest {
|
||||
initCrypto()
|
||||
val a = Random.Default.nextUBytes(1024)
|
||||
val x = Hash.Sha3AndBlake.digest(a)
|
||||
val p1 = x.sliceArray(0..31)
|
||||
val p2 = x.drop(32)
|
||||
assertContentEquals(Hash.Blake2b.digest(a), p1)
|
||||
assertContentEquals(Hash.Sha3_384.digest(a), p2)
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user