diff --git a/build.gradle.kts b/build.gradle.kts index 5a4a226..c862444 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -13,6 +13,7 @@ repositories { mavenCentral() mavenLocal() maven("https://maven.universablockchain.com/") + maven("https://gitea.sergeych.net/api/packages/SergeychWorks/maven") } kotlin { @@ -67,6 +68,7 @@ kotlin { api("net.sergeych:mp_bintools:0.0.6-SNAPSHOT") api("net.sergeych:mp_stools:1.4.1") + api("net.sergeych:crypto2:0.1.1-SNAPSHOT") } } val commonTest by getting { diff --git a/src/commonMain/kotlin/net/sergeych/crypto2/InitCrypto.kt b/src/commonMain/kotlin/net/sergeych/crypto2/InitCrypto.kt deleted file mode 100644 index 21199de..0000000 --- a/src/commonMain/kotlin/net/sergeych/crypto2/InitCrypto.kt +++ /dev/null @@ -1,27 +0,0 @@ -package net.sergeych.crypto2 - -import com.ionspin.kotlin.crypto.LibsodiumInitializer -import kotlinx.coroutines.sync.Mutex -import kotlinx.coroutines.sync.withLock - -private var isReady = false -private val readyAccess = Mutex() - -/** - * Library initialization: should be called before all other calls. - * It is safe and with little performance penalty to call it multiple times. - */ -suspend fun initCrypto() { - // faster to check with no lock - if( !isReady) { - readyAccess.withLock { - // recheck with lock, it could be ready by now - if( !isReady ) { - LibsodiumInitializer.initialize() - isReady = true - } - } - } -} - - diff --git a/src/commonMain/kotlin/net/sergeych/crypto2/Seal.kt b/src/commonMain/kotlin/net/sergeych/crypto2/Seal.kt deleted file mode 100644 index 33e5ff5..0000000 --- a/src/commonMain/kotlin/net/sergeych/crypto2/Seal.kt +++ /dev/null @@ -1,11 +0,0 @@ -package net.sergeych.crypto2 - -import kotlinx.serialization.Serializable - -@Serializable -class Seal( - val publicKey: SigningKey.Public, - val signature: UByteArray -) { - inline fun verify(message: UByteArray) = publicKey.verify(signature, message) -} \ No newline at end of file diff --git a/src/commonMain/kotlin/net/sergeych/crypto2/SignedBox.kt b/src/commonMain/kotlin/net/sergeych/crypto2/SignedBox.kt deleted file mode 100644 index 9431d1e..0000000 --- a/src/commonMain/kotlin/net/sergeych/crypto2/SignedBox.kt +++ /dev/null @@ -1,65 +0,0 @@ -package net.sergeych.crypto2 - -import kotlinx.serialization.Serializable -import kotlinx.serialization.Transient - -/** - * Multi-signed data box. Use [SignedBox.invoke] to easily create - * instances and [SignedBox.plus] to add more signatures (signing keys), and - * [SignedBox.contains] to check for a specific key signature presence. - * - * It is serializable and checks integrity on deserialization. If any of seals does not - * match the signed [message], it throws [IllegalSignatureException] _on deserialization_. - * E.g., if you have it deserialized, it is ok, check it contains all needed keys among - * signers. - * - * __The main constructor is used for deserializing only__. Don't use it directly unless you - * know what you are doing as it may be dangerous.Use one of the above to create or change it. - */ -@Serializable -class SignedBox( - val message: UByteArray, - private val seals: List, - @Transient - private val checkOnInit: Boolean = true -) { - - /** - * If this instance is not signed by a given key, return new instance signed also by this - * key, or return unchanged (same) object if it is already signed by this key; you - * _can't assume it always returns a copied object!_ - */ - operator fun plus(key: SigningKey.Secret): SignedBox = - if (key.publicKey in this) this - else SignedBox(message, seals + key.seal(message), false) - - /** - * Check that it is signed with a specified key. - */ - operator fun contains(publicKey: SigningKey.Public): Boolean { - return seals.any { it.publicKey == publicKey } - } - - init { - if (seals.isEmpty()) throw IllegalArgumentException("there should be at least one seal") - if (checkOnInit) { - if (!seals.all { it.verify(message) }) throw IllegalSignatureException() - } - } - - - companion object { - /** - * Create a new instance with a specific data sealed by one or more - * keys. At least one key is required to disallow providing not-signed - * instances, e.g. [SignedBox] is guaranteed to be properly sealed when - * successfully instantiated. - * - * @param data a message to sign - * @param keys a list of keys to sign with, should be at least one key. - * @throws IllegalArgumentException if keys are not specified. - */ - operator fun invoke(data: UByteArray, vararg keys: SigningKey.Secret): SignedBox = - SignedBox(data, keys.map { it.seal(data) }, false) - } -} \ No newline at end of file diff --git a/src/commonMain/kotlin/net/sergeych/crypto2/SigningKey.kt b/src/commonMain/kotlin/net/sergeych/crypto2/SigningKey.kt deleted file mode 100644 index cd38676..0000000 --- a/src/commonMain/kotlin/net/sergeych/crypto2/SigningKey.kt +++ /dev/null @@ -1,77 +0,0 @@ -package net.sergeych.crypto2 - -import com.ionspin.kotlin.crypto.signature.InvalidSignatureException -import com.ionspin.kotlin.crypto.signature.Signature -import kotlinx.serialization.SerialName -import kotlinx.serialization.Serializable -import net.sergeych.crypto2.SigningKey.Secret - -/** - * Keys in general: public, secret and later symmetric too. - * Keys could be compared to each other for equality and used - * as a Map keys (not sure about js). - * - * Use [Secret.pair] to create new keys. - */ -@Serializable -sealed class SigningKey { - abstract val packed: UByteArray - - override fun equals(other: Any?): Boolean { - return other is SigningKey && other.packed contentEquals packed - } - - override fun hashCode(): Int { - return packed.contentHashCode() - } - - override fun toString(): String = packed.encodeToBase64Url() - - /** - * Public key to verify signatures only - */ - @Serializable - @SerialName("p") - class Public(override val packed: UByteArray) : SigningKey() { - /** - * Verify the signature and return true if it is correct. - */ - fun verify(signature: UByteArray, message: UByteArray): Boolean = try { - Signature.verifyDetached(signature, message, packed) - true - } catch (_: InvalidSignatureException) { - false - } - - override fun toString(): String = "Pub:${super.toString()}" - - } - - /** - * Secret key to sign only - */ - @Serializable - @SerialName("s") - class Secret(override val packed: UByteArray) : SigningKey() { - - val publicKey: Public by lazy { - Public(Signature.ed25519SkToPk(packed)) - } - - fun sign(message: UByteArray): UByteArray = Signature.detached(message, packed) - - fun seal(message: UByteArray): Seal = Seal(this.publicKey, sign(message)) - override fun toString(): String = "Sct:${super.toString()}" - - companion object { - data class Pair(val signing: Secret, val aPublic: Public) - - fun pair(): Pair { - val p = Signature.keypair() - return Pair(Secret(p.secretKey), Public(p.publicKey)) - } - } - } -} - -class IllegalSignatureException: RuntimeException("signed data is tampered or signature is corrupted") diff --git a/src/commonMain/kotlin/net/sergeych/crypto2/contrail.kt b/src/commonMain/kotlin/net/sergeych/crypto2/contrail.kt deleted file mode 100644 index abfd8d9..0000000 --- a/src/commonMain/kotlin/net/sergeych/crypto2/contrail.kt +++ /dev/null @@ -1,7 +0,0 @@ -package net.sergeych.crypto2 - -import net.sergeych.bintools.CRC - -fun isValidContrail(data: UByteArray): Boolean = CRC.crc8(data.copyOfRange(1, data.size)) == data[0] - -fun createContrail(data: UByteArray): UByteArray = ubyteArrayOf(CRC.crc8(data)) + data \ No newline at end of file diff --git a/src/commonMain/kotlin/net/sergeych/crypto2/tools.kt b/src/commonMain/kotlin/net/sergeych/crypto2/tools.kt deleted file mode 100644 index cded97d..0000000 --- a/src/commonMain/kotlin/net/sergeych/crypto2/tools.kt +++ /dev/null @@ -1,111 +0,0 @@ -@file:Suppress("unused") - -package net.sergeych.crypto2 - -import com.ionspin.kotlin.crypto.secretbox.SecretBox -import com.ionspin.kotlin.crypto.secretbox.crypto_secretbox_NONCEBYTES -import com.ionspin.kotlin.crypto.util.LibsodiumRandom -import kotlinx.coroutines.channels.ReceiveChannel -import kotlinx.serialization.Serializable -import net.sergeych.bintools.toDataSource -import net.sergeych.bipack.BipackDecoder -import net.sergeych.bipack.BipackEncoder - -class DecryptionFailedException : RuntimeException("can't encrypt: wrong key or tampered message") - -@Serializable -data class WithNonce( - val cipherData: UByteArray, - val nonce: UByteArray, -) - -@Serializable -data class WithFill( - val data: UByteArray, - val safetyFill: UByteArray? = null -) { - constructor(data: UByteArray, fillSize: Int) : this(data, randomBytes(fillSize)) -} - -suspend fun readVarUnsigned(input: ReceiveChannel): UInt { - var result = 0u - var cnt = 0 - while(true) { - val b = input.receive().toUInt() - result = (result shl 7) or (b and 0x7fu) - if( (b and 0x80u) != 0u ) { - return result - } - if( ++cnt > 5 ) throw IllegalArgumentException("overflow while decoding varuint") - } -} - -fun encodeVarUnsigned(value: UInt): UByteArray { - val result = mutableListOf() - var rest = value - do { - val mask = if( rest <= 0x7fu ) 0x80u else 0u - result.add( (mask or (rest and 0x7fu)).toUByte() ) - rest = rest shr 7 - } while(rest != 0u) - return result.toUByteArray() -} - - -fun randomBytes(n: Int): UByteArray = if (n > 0) LibsodiumRandom.buf(n) else ubyteArrayOf() - -fun randomBytes(n: UInt): UByteArray = if (n > 0u) LibsodiumRandom.buf(n.toInt()) else ubyteArrayOf() - -/** - * Uniform random in `0 ..< max` range - */ -fun randomUInt(max: UInt) = LibsodiumRandom.uniform(max) -fun randomUInt(max: Int) = LibsodiumRandom.uniform(max.toUInt()) - -fun >T.limit(range: ClosedRange) = when { - this < range.start -> range.start - this > range.endInclusive -> range.endInclusive - else -> this -} - -fun >T.limitMax(max: T) = if( this < max ) this else max -fun >T.limitMin(min: T) = if( this > min ) this else min - -fun randomNonce(): UByteArray = randomBytes(crypto_secretbox_NONCEBYTES) - -/** - * Secret-key encrypt with authentication. - * Generates random nonce and add some random fill to protect - * against some analysis attacks. Nonce is included in the result. To be - * used with [decrypt]. - * @param secretKey a _secret_ key, see [SecretBox.keygen()] or like. - * @param plain data to encrypt - * @param fillSize number of random fill data to add. Use random value or default. - */ -fun encrypt( - secretKey: UByteArray, - plain: UByteArray, - fillSize: Int = randomUInt((plain.size * 3 / 10).limitMin(3)).toInt() -): UByteArray { - val filled = BipackEncoder.encode(WithFill(plain, fillSize)) - val nonce = randomNonce() - val encrypted = SecretBox.easy(filled.toUByteArray(), nonce, secretKey) - return BipackEncoder.encode(WithNonce(encrypted, nonce)).toUByteArray() -} - -/** - * Decrypt a secret-key-based message, normally encrypted with [encrypt]. - * @throws DecryptionFailedException if the key is wrong or a message is tampered with (MAC - * check failed). - */ -fun decrypt(secretKey: UByteArray, cipher: UByteArray): UByteArray { - val wn: WithNonce = BipackDecoder.decode(cipher.toDataSource()) - try { - return BipackDecoder.decode( - SecretBox.openEasy(wn.cipherData, wn.nonce, secretKey).toDataSource() - ).data - } - catch(_: com.ionspin.kotlin.crypto.secretbox.SecretBoxCorruptedOrTamperedDataExceptionOrInvalidKey) { - throw DecryptionFailedException() - } -} diff --git a/src/commonMain/kotlin/net/sergeych/crypto2/utools.kt b/src/commonMain/kotlin/net/sergeych/crypto2/utools.kt deleted file mode 100644 index c0bddea..0000000 --- a/src/commonMain/kotlin/net/sergeych/crypto2/utools.kt +++ /dev/null @@ -1,8 +0,0 @@ -package net.sergeych.crypto2 - -import net.sergeych.bintools.toDump -import net.sergeych.mp_tools.encodeToBase64Url - -fun UByteArray.toDump(wide: Boolean = false) = toByteArray().toDump(wide) - -fun UByteArray.encodeToBase64Url(): String = toByteArray().encodeToBase64Url() \ No newline at end of file diff --git a/src/commonMain/kotlin/net/sergeych/tools/AtomicCounter.kt b/src/commonMain/kotlin/net/sergeych/tools/AtomicCounter.kt deleted file mode 100644 index a70892a..0000000 --- a/src/commonMain/kotlin/net/sergeych/tools/AtomicCounter.kt +++ /dev/null @@ -1,9 +0,0 @@ -package net.sergeych.tools - -class AtomicCounter(initialValue: Long = 0) { - private val op = ProtectedOp() - var value: Long = initialValue - private set - - fun incrementAndGet(): Long = op { ++value } -} \ No newline at end of file diff --git a/src/commonMain/kotlin/net/sergeych/tools/ProtectedOp.kt b/src/commonMain/kotlin/net/sergeych/tools/ProtectedOp.kt deleted file mode 100644 index be9720c..0000000 --- a/src/commonMain/kotlin/net/sergeych/tools/ProtectedOp.kt +++ /dev/null @@ -1,21 +0,0 @@ -package net.sergeych.tools - -/** - * Multiplatform interface to perform a regular (not suspend) operation - * protected by a platform mutex (where necessary). Get real implementation - * with [ProtectedOp] - */ -interface ProtectedOpImplementation { - /** - * Call [f] iin mutually exclusive mode, it means that only one invocation - * can be active at a time, all the rest are waiting until the current operation - * will finish. - */ - operator fun invoke(f: ()->T): T -} - - -/** - * Get the platform-depended implementation of a mutex-protected operation. - */ -expect fun ProtectedOp(): ProtectedOpImplementation \ No newline at end of file diff --git a/src/commonMain/kotlin/net/sergeych/tools/flow_tools.kt b/src/commonMain/kotlin/net/sergeych/tools/flow_tools.kt deleted file mode 100644 index 6a01325..0000000 --- a/src/commonMain/kotlin/net/sergeych/tools/flow_tools.kt +++ /dev/null @@ -1,20 +0,0 @@ -package net.sergeych.tools - -import kotlinx.coroutines.cancel -import kotlinx.coroutines.coroutineScope -import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.launch - -/** - * suspend until the flow produces the value to which the - * predicate returns true - */ -suspend fun Flow.waitFor(predicate: (T)->Boolean) { - coroutineScope { - launch { - collect { - if( predicate(it) ) cancel() - } - } - } -} \ No newline at end of file diff --git a/src/commonMain/kotlin/net/sergeych/utools/collections.kt b/src/commonMain/kotlin/net/sergeych/utools/collections.kt deleted file mode 100644 index b33eba9..0000000 --- a/src/commonMain/kotlin/net/sergeych/utools/collections.kt +++ /dev/null @@ -1,12 +0,0 @@ -package net.sergeych.utools - -/** - * Scan the collection and return the first non-null result of the [predicate] on it. - * If all the elements give null with predicate call, returns null. - * - * Note that collection is scanned only to the first non-null predicate result. - */ -fun Collection.firstNonNull(predicate: (T)->R?): R? { - for( x in this ) predicate(x)?.let { return it } - return null -} \ No newline at end of file diff --git a/src/commonMain/kotlin/net/sergeych/utools/packing.kt b/src/commonMain/kotlin/net/sergeych/utools/packing.kt deleted file mode 100644 index 0b5ac85..0000000 --- a/src/commonMain/kotlin/net/sergeych/utools/packing.kt +++ /dev/null @@ -1,46 +0,0 @@ -package net.sergeych.utools - -import kotlinx.serialization.KSerializer -import kotlinx.serialization.serializer -import net.sergeych.bintools.toDataSource -import net.sergeych.bipack.BipackDecoder -import net.sergeych.bipack.BipackEncoder - -/** - * Effectively pack anyk nullable object. The result could be effectively packed - * in turn as a part of a more complex structure. - * - * To avoid packing non-null mark, - * we use a zero-size array, which, if in turn encoded, packs into a single - * zero byte. Thus, we avoid extra byte spending for unnecessary null - * check. - */ -inline fun pack(element: T?): UByteArray = pack(serializer(), element) - -/** - * Unpack nullable data packed with [pack] - */ -inline fun unpack(encoded: UByteArray): T = - unpack(serializer(), encoded) - -/** - * Effectively pack anyk nullable object. The result could be effectively packed - * in turn as a part of a more complex structure. - * - * To avoid packing non-null mark, - * we use a zero-size array, which, if in turn encoded, packs into a single - * zero byte. Thus, we avoid extra byte spending for unnecessary null - * check. - */ -fun pack(serializer: KSerializer, element: T?): UByteArray = - if (element == null) ubyteArrayOf() - else BipackEncoder.encode(serializer,element).toUByteArray() - - -/** - * Unpack nullable data packed with [pack] - */ -@Suppress("UNCHECKED_CAST") -fun unpack(serializer: KSerializer, encoded: UByteArray): T = - if (encoded.isEmpty()) null as T - else BipackDecoder.decode(encoded.toByteArray().toDataSource(),serializer) diff --git a/src/commonMain/kotlin/net/sergeych/utools/time.kt b/src/commonMain/kotlin/net/sergeych/utools/time.kt deleted file mode 100644 index 6c0ae50..0000000 --- a/src/commonMain/kotlin/net/sergeych/utools/time.kt +++ /dev/null @@ -1,12 +0,0 @@ -@file:Suppress("unused") - -package net.sergeych.utools - -import kotlinx.datetime.Clock -import kotlinx.datetime.Instant - -fun now(): Instant = Clock.System.now() -fun nowToSeconds(): Instant = Clock.System.now().truncateToSeconds() - -fun Instant.truncateToSeconds(): Instant = - Instant.fromEpochSeconds(toEpochMilliseconds()/1000) \ No newline at end of file diff --git a/src/commonMain/kotlin/org/komputing/khash/keccak/Keccak.kt b/src/commonMain/kotlin/org/komputing/khash/keccak/Keccak.kt deleted file mode 100644 index 6a45600..0000000 --- a/src/commonMain/kotlin/org/komputing/khash/keccak/Keccak.kt +++ /dev/null @@ -1,183 +0,0 @@ -package org.komputing.khash.keccak - -import com.ionspin.kotlin.bignum.integer.BigInteger -import org.komputing.khash.keccak.extensions.fillWith -import kotlin.math.min - -object Keccak { - - private val BIT_65 = BigInteger.ONE shl (64) - private val MAX_64_BITS = BIT_65 - BigInteger.ONE - - fun digest(value: ByteArray, parameter: KeccakParameter): ByteArray { - val uState = IntArray(200) - val uMessage = convertToUInt(value) - - var blockSize = 0 - var inputOffset = 0 - - // Absorbing phase - while (inputOffset < uMessage.size) { - blockSize = min(uMessage.size - inputOffset, parameter.rateInBytes) - for (i in 0 until blockSize) { - uState[i] = uState[i] xor uMessage[i + inputOffset] - } - - inputOffset += blockSize - - if (blockSize == parameter.rateInBytes) { - doF(uState) - blockSize = 0 - } - } - - // Padding phase - uState[blockSize] = uState[blockSize] xor parameter.d - if (parameter.d and 0x80 != 0 && blockSize == parameter.rateInBytes - 1) { - doF(uState) - } - - uState[parameter.rateInBytes - 1] = uState[parameter.rateInBytes - 1] xor 0x80 - doF(uState) - - // Squeezing phase - val byteResults = mutableListOf() - var tOutputLen = parameter.outputLengthInBytes - while (tOutputLen > 0) { - blockSize = min(tOutputLen, parameter.rateInBytes) - for (i in 0 until blockSize) { - byteResults.add(uState[i].toByte().toInt().toByte()) - } - - tOutputLen -= blockSize - if (tOutputLen > 0) { - doF(uState) - } - } - - return byteResults.toByteArray() - } - - private fun doF(uState: IntArray) { - val lState = Array(5) { Array(5) { BigInteger.ZERO } } - - for (i in 0..4) { - for (j in 0..4) { - val data = IntArray(8) - val index = 8 * (i + 5 * j) - uState.copyInto(data, 0, index, index + data.size) - lState[i][j] = convertFromLittleEndianTo64(data) - } - } - roundB(lState) - - uState.fillWith(0) - for (i in 0..4) { - for (j in 0..4) { - val data = convertFrom64ToLittleEndian(lState[i][j]) - data.copyInto(uState, 8 * (i + 5 * j)) - } - } - } - - /** - * Permutation on the given state. - */ - private fun roundB(state: Array>) { - var lfsrState = 1 - for (round in 0..23) { - val c = arrayOfNulls(5) - val d = arrayOfNulls(5) - - // θ step - for (i in 0..4) { - c[i] = state[i][0].xor(state[i][1]).xor(state[i][2]).xor(state[i][3]).xor(state[i][4]) - } - - for (i in 0..4) { - d[i] = c[(i + 4) % 5]!!.xor(c[(i + 1) % 5]!!.leftRotate64(1)) - } - - for (i in 0..4) { - for (j in 0..4) { - state[i][j] = state[i][j].xor(d[i]!!) - } - } - - // ρ and π steps - var x = 1 - var y = 0 - var current = state[x][y] - for (i in 0..23) { - val tX = x - x = y - y = (2 * tX + 3 * y) % 5 - - val shiftValue = current - current = state[x][y] - - state[x][y] = shiftValue.leftRotate64Safely((i + 1) * (i + 2) / 2) - } - - // χ step - for (j in 0..4) { - val t = arrayOfNulls(5) - for (i in 0..4) { - t[i] = state[i][j] - } - - for (i in 0..4) { - // ~t[(i + 1) % 5] - val invertVal = t[(i + 1) % 5]!!.xor(MAX_64_BITS) - // t[i] ^ ((~t[(i + 1) % 5]) & t[(i + 2) % 5]) - state[i][j] = t[i]!!.xor(invertVal.and(t[(i + 2) % 5]!!)) - } - } - - // ι step - for (i in 0..6) { - lfsrState = (lfsrState shl 1 xor (lfsrState shr 7) * 0x71) % 256 - // pow(2, i) - 1 - val bitPosition = (1 shl i) - 1 - if (lfsrState and 2 != 0) { - state[0][0] = state[0][0].xor(BigInteger.ONE shl bitPosition) - } - } - } - } - - /** - * Converts the given [data] array to an [IntArray] containing UInt values. - */ - private fun convertToUInt(data: ByteArray) = IntArray(data.size) { - data[it].toInt() and 0xFF - } - - /** - * Converts the given [data] array containing the little endian representation of a number to a [BigInteger]. - */ - private fun convertFromLittleEndianTo64(data: IntArray): BigInteger { - val value = data.map { it.toString(16) } - .map { if (it.length == 2) it else "0$it" } - .reversed() - .joinToString("") - return BigInteger.parseString(value, 16) - } - - /** - * Converts the given [BigInteger] to a little endian representation as an [IntArray]. - */ - private fun convertFrom64ToLittleEndian(uLong: BigInteger): IntArray { - val asHex = uLong.toString(16) - val asHexPadded = "0".repeat((8 * 2) - asHex.length) + asHex - return IntArray(8) { - ((7 - it) * 2).let { pos -> - asHexPadded.substring(pos, pos + 2).toInt(16) - } - } - } - - private fun BigInteger.leftRotate64Safely(rotate: Int) = leftRotate64(rotate % 64) - - private fun BigInteger.leftRotate64(rotate: Int) = (this shr (64 - rotate)).add(this shl rotate).mod(BIT_65) -} diff --git a/src/commonMain/kotlin/org/komputing/khash/keccak/KeccakParameter.kt b/src/commonMain/kotlin/org/komputing/khash/keccak/KeccakParameter.kt deleted file mode 100644 index 57570e9..0000000 --- a/src/commonMain/kotlin/org/komputing/khash/keccak/KeccakParameter.kt +++ /dev/null @@ -1,22 +0,0 @@ -@file:Suppress("unused") - -package org.komputing.khash.keccak - -/** - * Parameters defining the FIPS 202 standard. - */ -enum class KeccakParameter(val rateInBytes: Int,val outputLengthInBytes: Int, val d: Int) { - - KECCAK_224(144, 28, 0x01), - KECCAK_256(136, 32, 0x01), - KECCAK_384(104, 48, 0x01), - KECCAK_512(72, 64, 0x01), - - SHA3_224(144, 28, 0x06), - SHA3_256(136, 32, 0x06), - SHA3_384(104, 48, 0x06), - SHA3_512(72, 64, 0x06), - - SHAKE128(168, 32, 0x1F), - SHAKE256(136, 64, 0x1F) -} diff --git a/src/commonMain/kotlin/org/komputing/khash/keccak/extensions/IntArrayExtensions.kt b/src/commonMain/kotlin/org/komputing/khash/keccak/extensions/IntArrayExtensions.kt deleted file mode 100644 index c36c21a..0000000 --- a/src/commonMain/kotlin/org/komputing/khash/keccak/extensions/IntArrayExtensions.kt +++ /dev/null @@ -1,42 +0,0 @@ -package org.komputing.khash.keccak.extensions - -/** - * Assigns the specified int value to each element of the specified - * range in the specified array of ints. The range to be filled - * extends from index fromIndex, inclusive, to index - * toIndex, exclusive. (If fromIndex==toIndex, the - * range to be filled is empty.) - * - * @param fromIndex the index of the first element (inclusive) to be - * filled with the specified value - * @param toIndex the index of the last element (exclusive) to be - * filled with the specified value - * @param value the value to be stored in all elements of the array - * @throws IllegalArgumentException if fromIndex > toIndex - * @throws ArrayIndexOutOfBoundsException if fromIndex < 0 or - * toIndex > a.length - */ -internal fun IntArray.fillWith(value: Int, fromIndex: Int = 0, toIndex: Int = this.size) { - if (fromIndex > toIndex) { - throw IllegalArgumentException( - "fromIndex($fromIndex) > toIndex($toIndex)" - ) - } - - if (fromIndex < 0) { - throw ArrayIndexOutOfBoundsException(fromIndex) - } - if (toIndex > this.size) { - throw ArrayIndexOutOfBoundsException(toIndex) - } - - for (i in fromIndex until toIndex) - this[i] = value -} - -/** - * Constructs a new [ArrayIndexOutOfBoundsException] - * class with an argument indicating the illegal index. - * @param index the illegal index. - */ -internal class ArrayIndexOutOfBoundsException(index: Int) : Throwable("Array index out of range: $index") diff --git a/src/commonMain/kotlin/org/komputing/khash/keccak/extensions/PublicExtensions.kt b/src/commonMain/kotlin/org/komputing/khash/keccak/extensions/PublicExtensions.kt deleted file mode 100644 index d68f972..0000000 --- a/src/commonMain/kotlin/org/komputing/khash/keccak/extensions/PublicExtensions.kt +++ /dev/null @@ -1,19 +0,0 @@ -@file:Suppress("unused") -package org.komputing.khash.keccak.extensions - -import org.komputing.khash.keccak.Keccak -import org.komputing.khash.keccak.KeccakParameter - -/** - * Computes the proper Keccak digest of [this] byte array based on the given [parameter] - */ -fun ByteArray.digestKeccak(parameter: KeccakParameter): ByteArray { - return Keccak.digest(this, parameter) -} - -/** - * Computes the proper Keccak digest of [this] string based on the given [parameter] - */ -fun String.digestKeccak(parameter: KeccakParameter): ByteArray { - return Keccak.digest(encodeToByteArray(), parameter) -} diff --git a/src/commonTest/kotlin/KeysTest.kt b/src/commonTest/kotlin/KeysTest.kt index 5b3437d..fd90354 100644 --- a/src/commonTest/kotlin/KeysTest.kt +++ b/src/commonTest/kotlin/KeysTest.kt @@ -11,7 +11,7 @@ class KeysTest { @Test fun testCreationAndMap() = runTest { initCrypto() - val (stk,pbk) = SigningKey.Secret.pair() + val (stk,pbk) = SigningKey.pair() val x = mapOf( stk to "STK!", pbk to "PBK!") assertEquals("STK!", x[stk]) @@ -22,22 +22,22 @@ class KeysTest { val data = "8 rays dev!".encodeToUByteArray() val data1 = "8 rays dev!".encodeToUByteArray() - val s = SignedBox.Seal.create(stk, data) + val s = stk.seal(data) assertTrue(s.verify(data)) data1[0] = 0x01u assertFalse(s.verify(data1)) - val p2 = SigningKey.Secret.pair() - val p3 = SigningKey.Secret.pair() + val p2 = SigningKey.pair() + val p3 = SigningKey.pair() - val ms = SignedBox(data, s1) + p2.signing + val ms = SignedBox(data, s1) + p2.secretKey // non tampered: val ms1 = unpack(pack(ms)) assertContentEquals(data, ms1.message) assertTrue(pbk in ms1) - assertTrue(p2.aPublic in ms1) - assertTrue(p3.aPublic !in ms1) + assertTrue(p2.publicKey in ms1) + assertTrue(p3.publicKey !in ms1) assertThrows { unpack(pack(ms).also { it[3] = 1u }) diff --git a/src/commonTest/kotlin/TransportTest.kt b/src/commonTest/kotlin/TransportTest.kt index 60ca099..254af21 100644 --- a/src/commonTest/kotlin/TransportTest.kt +++ b/src/commonTest/kotlin/TransportTest.kt @@ -171,8 +171,8 @@ class TransportTest { // Log.defaultLevel = Log.Level.DEBUG val (d1, d2) = createTestDevice() - val serverId = SigningKey.Secret.pair() - val clientId = SigningKey.Secret.pair() + val serverId = SigningKey.pair() + val clientId = SigningKey.pair() val serverInterface = KiloInterface().apply { on(cmdPing) { @@ -193,13 +193,13 @@ class TransportTest { registerError { IllegalStateException() } registerError { IllegalArgumentException(it) } } - val kiloServerConnection = KiloServerConnection(serverInterface, d1, "server session", serverId.signing) + val kiloServerConnection = KiloServerConnection(serverInterface, d1, "server session", serverId.secretKey) launch { kiloServerConnection.run() } var cnt = 0 val client = KiloClient { session { "client session!" } - secretIdKey = clientId.signing + secretIdKey = clientId.secretKey local { on(cmdPush) { "server push: $it" diff --git a/src/jsMain/kotlin/net/sergeych/tools/ProtectedOp.js.kt b/src/jsMain/kotlin/net/sergeych/tools/ProtectedOp.js.kt deleted file mode 100644 index acd7d7d..0000000 --- a/src/jsMain/kotlin/net/sergeych/tools/ProtectedOp.js.kt +++ /dev/null @@ -1,6 +0,0 @@ -package net.sergeych.tools - -actual fun ProtectedOp(): ProtectedOpImplementation = object : ProtectedOpImplementation { - // JS targets are inherently single-threaded, so we do noting: - override fun invoke(f: () -> T): T = f() -} \ No newline at end of file diff --git a/src/jvmMain/kotlin/net/sergeych/tools/ProtectedOp.jvm.kt b/src/jvmMain/kotlin/net/sergeych/tools/ProtectedOp.jvm.kt deleted file mode 100644 index 1114558..0000000 --- a/src/jvmMain/kotlin/net/sergeych/tools/ProtectedOp.jvm.kt +++ /dev/null @@ -1,8 +0,0 @@ -package net.sergeych.tools - -actual fun ProtectedOp(): ProtectedOpImplementation = object : ProtectedOpImplementation { - private val lock = Object() - override fun invoke(f: () -> T): T { - synchronized(lock) { return f() } - } -} \ No newline at end of file diff --git a/src/nativeMain/kotlin/net/sergeych/tools/ProtectedOp.native.kt b/src/nativeMain/kotlin/net/sergeych/tools/ProtectedOp.native.kt deleted file mode 100644 index c772602..0000000 --- a/src/nativeMain/kotlin/net/sergeych/tools/ProtectedOp.native.kt +++ /dev/null @@ -1,13 +0,0 @@ -package net.sergeych.tools - -import kotlinx.atomicfu.locks.SynchronizedObject -import kotlinx.atomicfu.locks.synchronized - -actual fun ProtectedOp(): ProtectedOpImplementation = object : ProtectedOpImplementation { - private val lock = SynchronizedObject() - override fun invoke(f: () -> T): T { - synchronized(lock) { - return f() - } - } -} \ No newline at end of file