forked from sergeych/crypto2
		
	Compare commits
	
		
			7 Commits
		
	
	
		
			e8d6b2fc02
			...
			e2d4fb07ad
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| e2d4fb07ad | |||
| d180da309b | |||
| c9e3c57ee2 | |||
| 81e02ac88e | |||
| 277dc62553 | |||
| 7fa3ab1ca8 | |||
| 242cc7d0f5 | 
@ -114,4 +114,13 @@ Secret key encryption and signing/verifying uses Edwards curves 25519 algorithms
 | 
			
		||||
  - SHA3 256, 384, more are on the way.
 | 
			
		||||
- CRC-protected binary ID with magic numbers to implement human-friendly IDS with type checks
 | 
			
		||||
 | 
			
		||||
## Licensing
 | 
			
		||||
 | 
			
		||||
# Licensing
 | 
			
		||||
 | 
			
		||||
This is work in progress, not yet moved to public domain;
 | 
			
		||||
you need to obtain a license from https://8-rays.dev or [Sergey Chernov]. For open source projects it will most be free on some special terms.
 | 
			
		||||
 | 
			
		||||
It will be moved to open source; we also guarantee that it will be moved to open source immediately if the software export restrictions will be lifted. We do not support such practices here at 8-rays.dev and assume open source must be open.
 | 
			
		||||
 | 
			
		||||
[Sergey Chernov]: https://t.me/real_sergeych
 | 
			
		||||
							
								
								
									
										10
									
								
								bin/pubdocs
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								bin/pubdocs
									
									
									
									
									
								
							@ -1,4 +1,14 @@
 | 
			
		||||
#!/bin/bash
 | 
			
		||||
#
 | 
			
		||||
# Copyright (c) 2025. Sergey S. Chernov - All Rights Reserved
 | 
			
		||||
#
 | 
			
		||||
#  You may use, distribute and modify this code under the
 | 
			
		||||
# terms of the private license, which you must obtain from the author
 | 
			
		||||
#
 | 
			
		||||
# To obtain the license, contact the author: https://t.me/real_sergeych or email to
 | 
			
		||||
# real dot sergeych at gmail.
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
set -e
 | 
			
		||||
./gradlew dokkaHtml
 | 
			
		||||
rsync -avz ./build/dokka/* code.sergeych.net:/bigstore/sergeych_pub/code/docs/crypto2
 | 
			
		||||
 | 
			
		||||
@ -1,5 +1,14 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2025. Sergey S. Chernov - All Rights Reserved
 | 
			
		||||
 *
 | 
			
		||||
 *  You may use, distribute and modify this code under the
 | 
			
		||||
 * terms of the private license, which you must obtain from the author
 | 
			
		||||
 *
 | 
			
		||||
 * To obtain the license, contact the author: https://t.me/real_sergeych or email to
 | 
			
		||||
 * real dot sergeych at gmail.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
import org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi
 | 
			
		||||
import org.jetbrains.kotlin.gradle.ExperimentalWasmDsl
 | 
			
		||||
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
 | 
			
		||||
 | 
			
		||||
plugins {
 | 
			
		||||
@ -10,13 +19,13 @@ plugins {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
group = "net.sergeych"
 | 
			
		||||
version = "0.7.1-SNAPSHOT"
 | 
			
		||||
version = "0.7.4-SNAPSHOT"
 | 
			
		||||
 | 
			
		||||
repositories {
 | 
			
		||||
    mavenCentral()
 | 
			
		||||
    maven("https://maven.universablockchain.com/")
 | 
			
		||||
    maven("https://gitea.sergeych.net/api/packages/SergeychWorks/maven")
 | 
			
		||||
    maven("https://gitea.sergeych.net/api/packages/YoungBlood/maven")
 | 
			
		||||
//    maven("https://gitea.sergeych.net/api/packages/YoungBlood/maven")
 | 
			
		||||
    mavenLocal()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -40,10 +49,10 @@ kotlin {
 | 
			
		||||
    iosArm64()
 | 
			
		||||
    iosSimulatorArm64()
 | 
			
		||||
    mingwX64()
 | 
			
		||||
    @OptIn(ExperimentalWasmDsl::class)
 | 
			
		||||
    wasmJs {
 | 
			
		||||
        browser()
 | 
			
		||||
    }
 | 
			
		||||
//    @OptIn(ExperimentalWasmDsl::class)
 | 
			
		||||
//    wasmJs {
 | 
			
		||||
//        browser()
 | 
			
		||||
//    }
 | 
			
		||||
    val ktor_version = "2.3.6"
 | 
			
		||||
 | 
			
		||||
    sourceSets {
 | 
			
		||||
@ -87,18 +96,18 @@ kotlin {
 | 
			
		||||
        for (platform in listOf(linuxX64Main, linuxArm64Main, macosX64Main, macosArm64Main, iosX64Main, iosArm64Main, iosSimulatorArm64Main, mingwX64Main))
 | 
			
		||||
            platform { dependsOn(native) }
 | 
			
		||||
 | 
			
		||||
        val wasmJsMain by getting {
 | 
			
		||||
            val wasmJsTargetRegex = Regex(pattern = "wasmJs.*")
 | 
			
		||||
            configurations.all {
 | 
			
		||||
                if (wasmJsTargetRegex.containsMatchIn(input = this.name)) {
 | 
			
		||||
                    resolutionStrategy.dependencySubstitution {
 | 
			
		||||
                        substitute(module("com.ionspin.kotlin:multiplatform-crypto-libsodium-bindings:0.9.2"))
 | 
			
		||||
                            .using(module("net.sergeych:multiplatform-crypto-libsodium-bindings:0.9.4-SNAPSHOT"))
 | 
			
		||||
                            .withoutClassifier()
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
//        val wasmJsMain by getting {
 | 
			
		||||
//            val wasmJsTargetRegex = Regex(pattern = "wasmJs.*")
 | 
			
		||||
//            configurations.all {
 | 
			
		||||
//                if (wasmJsTargetRegex.containsMatchIn(input = this.name)) {
 | 
			
		||||
//                    resolutionStrategy.dependencySubstitution {
 | 
			
		||||
//                        substitute(module("com.ionspin.kotlin:multiplatform-crypto-libsodium-bindings:0.9.2"))
 | 
			
		||||
//                            .using(module("net.sergeych:multiplatform-crypto-libsodium-bindings:0.9.4-SNAPSHOT"))
 | 
			
		||||
//                            .withoutClassifier()
 | 
			
		||||
//                    }
 | 
			
		||||
//                }
 | 
			
		||||
//            }
 | 
			
		||||
//        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1 +1,11 @@
 | 
			
		||||
#
 | 
			
		||||
# Copyright (c) 2025. Sergey S. Chernov - All Rights Reserved
 | 
			
		||||
#
 | 
			
		||||
#  You may use, distribute and modify this code under the
 | 
			
		||||
# terms of the private license, which you must obtain from the author
 | 
			
		||||
#
 | 
			
		||||
# To obtain the license, contact the author: https://t.me/real_sergeych or email to
 | 
			
		||||
# real dot sergeych at gmail.
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
kotlin.code.style=official
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										10
									
								
								gradle/wrapper/gradle-wrapper.properties
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										10
									
								
								gradle/wrapper/gradle-wrapper.properties
									
									
									
									
										vendored
									
									
								
							@ -1,3 +1,13 @@
 | 
			
		||||
#
 | 
			
		||||
# Copyright (c) 2025. Sergey S. Chernov - All Rights Reserved
 | 
			
		||||
#
 | 
			
		||||
#  You may use, distribute and modify this code under the
 | 
			
		||||
# terms of the private license, which you must obtain from the author
 | 
			
		||||
#
 | 
			
		||||
# To obtain the license, contact the author: https://t.me/real_sergeych or email to
 | 
			
		||||
# real dot sergeych at gmail.
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
distributionBase=GRADLE_USER_HOME
 | 
			
		||||
distributionPath=wrapper/dists
 | 
			
		||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.2-bin.zip
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										16
									
								
								gradlew
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										16
									
								
								gradlew
									
									
									
									
										vendored
									
									
								
							@ -1,19 +1,13 @@
 | 
			
		||||
#!/bin/sh
 | 
			
		||||
 | 
			
		||||
#
 | 
			
		||||
# Copyright © 2015-2021 the original authors.
 | 
			
		||||
# Copyright (c) 2025. Sergey S. Chernov - All Rights Reserved
 | 
			
		||||
#
 | 
			
		||||
# Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
# you may not use this file except in compliance with the License.
 | 
			
		||||
# You may obtain a copy of the License at
 | 
			
		||||
#  You may use, distribute and modify this code under the
 | 
			
		||||
# terms of the private license, which you must obtain from the author
 | 
			
		||||
#
 | 
			
		||||
#      https://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
#
 | 
			
		||||
# Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
# distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
# See the License for the specific language governing permissions and
 | 
			
		||||
# limitations under the License.
 | 
			
		||||
# To obtain the license, contact the author: https://t.me/real_sergeych or email to
 | 
			
		||||
# real dot sergeych at gmail.
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
##############################################################################
 | 
			
		||||
 | 
			
		||||
@ -1,3 +1,13 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2025. Sergey S. Chernov - All Rights Reserved
 | 
			
		||||
 *
 | 
			
		||||
 *  You may use, distribute and modify this code under the
 | 
			
		||||
 * terms of the private license, which you must obtain from the author
 | 
			
		||||
 *
 | 
			
		||||
 * To obtain the license, contact the author: https://t.me/real_sergeych or email to
 | 
			
		||||
 * real dot sergeych at gmail.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
pluginManagement {
 | 
			
		||||
    repositories {
 | 
			
		||||
        mavenCentral()
 | 
			
		||||
 | 
			
		||||
@ -1,3 +1,13 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2025. Sergey S. Chernov - All Rights Reserved
 | 
			
		||||
 *
 | 
			
		||||
 *  You may use, distribute and modify this code under the
 | 
			
		||||
 * terms of the private license, which you must obtain from the author
 | 
			
		||||
 *
 | 
			
		||||
 * To obtain the license, contact the author: https://t.me/real_sergeych or email to
 | 
			
		||||
 * real dot sergeych at gmail.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package net.sergeych.crypto2
 | 
			
		||||
 | 
			
		||||
import com.ionspin.kotlin.crypto.box.Box
 | 
			
		||||
@ -14,10 +24,10 @@ import net.sergeych.crypto2.Asymmetric.generateKeys
 | 
			
		||||
 *
 | 
			
		||||
 * ## How to
 | 
			
		||||
 *
 | 
			
		||||
 * - [SecretKey.new] to create a secret key that includes [SecretKey.publicKey].
 | 
			
		||||
 * - [DecryptingSecretKey.new] to create a secret key that includes [DecryptingSecretKey.publicKey].
 | 
			
		||||
 *   [generateKeys] also makes the pair.
 | 
			
		||||
 * - [PublicKey] provides encryption, anonymous or authenticated.
 | 
			
		||||
 * - [SecretKey] provides authenticated decryption of what [PublicKey] was encrypted with.
 | 
			
		||||
 * - [EncryptingPublicKey] provides encryption, anonymous or authenticated.
 | 
			
		||||
 * - [DecryptingSecretKey] provides authenticated decryption of what [EncryptingPublicKey] was encrypted with.
 | 
			
		||||
 * - [Message] is a serializable container with all necessary data to decrypt public-key encrypted data it.
 | 
			
		||||
 *
 | 
			
		||||
 * __Algorithms:__
 | 
			
		||||
@ -31,8 +41,8 @@ object Asymmetric {
 | 
			
		||||
    /**
 | 
			
		||||
     * Encrypted message holder.
 | 
			
		||||
     *
 | 
			
		||||
     * Do not instantiate it directly, use [PublicKey.encryptMessage], [PublicKey.encryptAnonymousMessage], etc.
 | 
			
		||||
     * instead. Also [SecretKey.decrypt] can be used to decrypt it same as [decrypt] or [decryptWithSenderKey].
 | 
			
		||||
     * Do not instantiate it directly, use [EncryptingPublicKey.encryptMessage], [EncryptingPublicKey.encryptAnonymousMessage], etc.
 | 
			
		||||
     * instead. Also [DecryptingSecretKey.decrypt] can be used to decrypt it same as [decrypt] or [decryptWithSenderKey].
 | 
			
		||||
     *
 | 
			
		||||
     * To successfully decrypt the message, it is necessary to know a sender public key, and non-secret nonce.
 | 
			
		||||
     * This class carries all this information; serialize and pass it to the recipient.
 | 
			
		||||
@ -41,12 +51,12 @@ object Asymmetric {
 | 
			
		||||
    class Message(
 | 
			
		||||
        private val nonce: UByteArray,
 | 
			
		||||
        private val encryptedMessage: UByteArray,
 | 
			
		||||
        val senderPublicKey: PublicKey,
 | 
			
		||||
        val senderPublicKey: EncryptingPublicKey,
 | 
			
		||||
    ) {
 | 
			
		||||
        /**
 | 
			
		||||
         * Decrypt the message, same as [SecretKey.decrypt]
 | 
			
		||||
         * Decrypt the message, same as [DecryptingSecretKey.decrypt]
 | 
			
		||||
         */
 | 
			
		||||
        fun decrypt(recipientKey: SecretKey): UByteArray {
 | 
			
		||||
        fun decrypt(recipientKey: DecryptingSecretKey): UByteArray {
 | 
			
		||||
            return decryptWithSenderKey(senderPublicKey, recipientKey)
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@ -54,7 +64,7 @@ object Asymmetric {
 | 
			
		||||
         * Decrypt a message which is not include sender's public key (which should somehow be
 | 
			
		||||
         * known to the recipient). Use it if [senderPublicKey] is null.
 | 
			
		||||
         */
 | 
			
		||||
        fun decryptWithSenderKey(senderKey: PublicKey, recipientKey: SecretKey): UByteArray {
 | 
			
		||||
        fun decryptWithSenderKey(senderKey: EncryptingPublicKey, recipientKey: DecryptingSecretKey): UByteArray {
 | 
			
		||||
            return try {
 | 
			
		||||
                WithFill.decode(
 | 
			
		||||
                    Box.openEasy(encryptedMessage, nonce, senderKey.keyBytes, recipientKey.keyBytes)
 | 
			
		||||
@ -79,19 +89,19 @@ object Asymmetric {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Encrypt the [plainData] using [from] sender for [recipient] public key. Note that to decrypt it
 | 
			
		||||
     * the [SecretKey] that corresponds to the [recipient] public key is needed, Sender can't decrypt the message!
 | 
			
		||||
     * the [DecryptingSecretKey] that corresponds to the [recipient] public key is needed, Sender can't decrypt the message!
 | 
			
		||||
     *
 | 
			
		||||
     * The authenticated encryption is used, is the message _is successfully decrypted_, it also means that
 | 
			
		||||
     * it was signed by the sender, whose public key is known at the decryption time.
 | 
			
		||||
     *
 | 
			
		||||
     * When it is important not to provide senders' key, use [PublicKey.encryptAnonymousMessage].
 | 
			
		||||
     * When it is important not to provide senders' key, use [EncryptingPublicKey.encryptAnonymousMessage].
 | 
			
		||||
     *
 | 
			
		||||
     * @param from the senders' secret key.
 | 
			
		||||
     * @param recipient the recipients' public key.
 | 
			
		||||
     * @param plainData data to encrypt
 | 
			
		||||
     */
 | 
			
		||||
    internal fun createMessage(
 | 
			
		||||
        from: SecretKey, recipient: PublicKey, plainData: UByteArray,
 | 
			
		||||
        from: DecryptingSecretKey, recipient: EncryptingPublicKey, plainData: UByteArray,
 | 
			
		||||
        nonce: UByteArray = randomNonce(),
 | 
			
		||||
    ): Message {
 | 
			
		||||
        return Message(
 | 
			
		||||
@ -104,8 +114,8 @@ object Asymmetric {
 | 
			
		||||
 | 
			
		||||
    private fun randomNonce(): UByteArray = randomUBytes(crypto_box_NONCEBYTES)
 | 
			
		||||
 | 
			
		||||
    fun generateKeys() = SecretKey.generateKeys()
 | 
			
		||||
    fun newSecretKey() = SecretKey.new()
 | 
			
		||||
    fun generateKeys() = DecryptingSecretKey.generateKeys()
 | 
			
		||||
    fun newSecretKey() = DecryptingSecretKey.new()
 | 
			
		||||
 | 
			
		||||
    val nonceBytesLength = crypto_box_NONCEBYTES
 | 
			
		||||
 | 
			
		||||
@ -115,4 +125,4 @@ object Asymmetric {
 | 
			
		||||
 * Shortcut type: a pair of sender secret key and recipient private key could be used so
 | 
			
		||||
 * simplify such interfaces
 | 
			
		||||
 */
 | 
			
		||||
typealias AsymmetricEncryptionPair = Pair<SecretKey?, PublicKey>
 | 
			
		||||
typealias AsymmetricEncryptionPair = Pair<DecryptingSecretKey?, EncryptingPublicKey>
 | 
			
		||||
 | 
			
		||||
@ -1,3 +1,13 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2025. Sergey S. Chernov - All Rights Reserved
 | 
			
		||||
 *
 | 
			
		||||
 *  You may use, distribute and modify this code under the
 | 
			
		||||
 * terms of the private license, which you must obtain from the author
 | 
			
		||||
 *
 | 
			
		||||
 * To obtain the license, contact the author: https://t.me/real_sergeych or email to
 | 
			
		||||
 * real dot sergeych at gmail.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package net.sergeych.crypto2
 | 
			
		||||
 | 
			
		||||
import com.ionspin.kotlin.crypto.util.encodeToUByteArray
 | 
			
		||||
@ -48,7 +58,7 @@ open class BinaryId(
 | 
			
		||||
    /**
 | 
			
		||||
     * Bad format (crc does not match)
 | 
			
		||||
     */
 | 
			
		||||
    class InvalidException(text: String,reason: Throwable?=null) : IllegalArgumentException(text,reason)
 | 
			
		||||
    class InvalidException(text: String, reason: Throwable? = null) : IllegalArgumentException(text, reason)
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Attempt to compare binary ids with different magic. In this case only [equals]
 | 
			
		||||
@ -70,32 +80,32 @@ open class BinaryId(
 | 
			
		||||
        rest.last().toInt()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private val innerData: UByteArray by lazy { id.sliceArray( 1..< id.size-1 ) }
 | 
			
		||||
    private val innerData: UByteArray by lazy { id.sliceArray(1..<id.size - 1) }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * The ID body: all the bytes except check and magic. ID bytes could carry useful information.
 | 
			
		||||
     *
 | 
			
		||||
     * - `id.size` is [body] size + 2 (see [BinaryId] inner structure)
 | 
			
		||||
     */
 | 
			
		||||
    val body: UByteArray by lazy { id.sliceArray( 0 until id.size-2 ) }
 | 
			
		||||
    val body: UByteArray by lazy { id.sliceArray(0 until id.size - 2) }
 | 
			
		||||
 | 
			
		||||
    val asVerifyingKey: VerifyingKey by lazy {
 | 
			
		||||
        if( magic != KeysmagicNumber.defaultVerifying.ordinal)
 | 
			
		||||
        if (magic != KeysmagicNumber.defaultVerifying.ordinal)
 | 
			
		||||
            throw InvalidException("It is not a veryfing key: magic=$magic, required ${KeysmagicNumber.defaultVerifying.ordinal}")
 | 
			
		||||
        check(body.size == 32)
 | 
			
		||||
        VerifyingPublicKey(body)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Try to recnstruct a [PublicKey] from [id] bytes. For such keys, [PublicKey.id] and [SecretKey.id]
 | 
			
		||||
     * Try to recnstruct a [EncryptingPublicKey] from [id] bytes. For such keys, [EncryptingPublicKey.id] and [DecryptingSecretKey.id]
 | 
			
		||||
     * are made from public key bytes so it could be restored from such an ID
 | 
			
		||||
     *
 | 
			
		||||
     */
 | 
			
		||||
    val asPublicKey: PublicKey by lazy {
 | 
			
		||||
        if( magic != KeysmagicNumber.defaultAssymmetric.ordinal)
 | 
			
		||||
    val asPublicKey: EncryptingPublicKey by lazy {
 | 
			
		||||
        if (magic != KeysmagicNumber.defaultAssymmetric.ordinal)
 | 
			
		||||
            throw InvalidException("It is not a veryfing key: magic=$magic, required ${KeysmagicNumber.defaultAssymmetric.ordinal}")
 | 
			
		||||
        check(body.size == 32)
 | 
			
		||||
        PublicKey(body)
 | 
			
		||||
        EncryptingPublicKey(body)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    override fun toString(): String = id.encodeToBase64Url()
 | 
			
		||||
@ -157,8 +167,8 @@ open class BinaryId(
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @Suppress("unused")
 | 
			
		||||
        fun createRandom(magicNumber: Int, size: Int=16) =
 | 
			
		||||
            createFromBytes(magicNumber, Random.Default.nextBytes(size-2))
 | 
			
		||||
        fun createRandom(magicNumber: Int, size: Int = 16) =
 | 
			
		||||
            createFromBytes(magicNumber, Random.Default.nextBytes(size - 2))
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Encode a string as UTF and create a binaryId from its bytes and provided magic.
 | 
			
		||||
 | 
			
		||||
@ -1,3 +1,13 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2025. Sergey S. Chernov - All Rights Reserved
 | 
			
		||||
 *
 | 
			
		||||
 *  You may use, distribute and modify this code under the
 | 
			
		||||
 * terms of the private license, which you must obtain from the author
 | 
			
		||||
 *
 | 
			
		||||
 * To obtain the license, contact the author: https://t.me/real_sergeych or email to
 | 
			
		||||
 * real dot sergeych at gmail.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package net.sergeych.crypto2
 | 
			
		||||
 | 
			
		||||
import kotlinx.serialization.Serializable
 | 
			
		||||
 | 
			
		||||
@ -1,3 +1,13 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2025. Sergey S. Chernov - All Rights Reserved
 | 
			
		||||
 *
 | 
			
		||||
 *  You may use, distribute and modify this code under the
 | 
			
		||||
 * terms of the private license, which you must obtain from the author
 | 
			
		||||
 *
 | 
			
		||||
 * To obtain the license, contact the author: https://t.me/real_sergeych or email to
 | 
			
		||||
 * real dot sergeych at gmail.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package net.sergeych.crypto2
 | 
			
		||||
 | 
			
		||||
import kotlinx.serialization.SerialName
 | 
			
		||||
@ -24,8 +34,8 @@ import net.sergeych.crypto2.Container.Companion.createWith
 | 
			
		||||
 *
 | 
			
		||||
 * Some rules:
 | 
			
		||||
 *
 | 
			
		||||
 * When adding public key recipient, it is faster to use your known [SecretKey], but you
 | 
			
		||||
 * can stay anonymous by just adding [PublicKey] only.
 | 
			
		||||
 * When adding public key recipient, it is faster to use your known [DecryptingSecretKey], but you
 | 
			
		||||
 * can stay anonymous by just adding [EncryptingPublicKey] only.
 | 
			
		||||
 *
 | 
			
		||||
 * Put your data in [SealedBox] if you need to authenticate message origin and timestamp, then put
 | 
			
		||||
 * the sealed box in the [Container], this will conceal signers from attack. In the case you need to
 | 
			
		||||
@ -107,7 +117,7 @@ sealed class Container {
 | 
			
		||||
     * Add e key to the __decrypted__ container. The new container is also decrypted so you can add
 | 
			
		||||
     * more keys, etc.
 | 
			
		||||
     */
 | 
			
		||||
    operator fun plus(recipient: PublicKey) = addRecipients { key(recipient) }
 | 
			
		||||
    operator fun plus(recipient: EncryptingPublicKey) = addRecipients { key(recipient) }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Add e key to the __decrypted__ container. The new container is also decrypted so you can add
 | 
			
		||||
@ -119,7 +129,7 @@ sealed class Container {
 | 
			
		||||
     * Add e key to the __decrypted__ container. The new container is also decrypted so you can add
 | 
			
		||||
     * more keys, etc.
 | 
			
		||||
     */
 | 
			
		||||
    operator fun plus(pair: Pair<SecretKey, PublicKey>) = addRecipients { key(pair) }
 | 
			
		||||
    operator fun plus(pair: Pair<DecryptingSecretKey, EncryptingPublicKey>) = addRecipients { key(pair) }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Update the data in the decrypted container. It keeps the same set of keys and update
 | 
			
		||||
@ -145,14 +155,14 @@ sealed class Container {
 | 
			
		||||
    abstract val decryptedWithKeyId: KeyId?
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * If the container _is decrypted by the [PublicKey]_, e.g., using secret key encryption,
 | 
			
		||||
     * contains the [PublicKey] that corresponds the [SecretKey] used while encrypting, this
 | 
			
		||||
     * If the container _is decrypted by the [EncryptingPublicKey]_, e.g., using secret key encryption,
 | 
			
		||||
     * contains the [EncryptingPublicKey] that corresponds the [DecryptingSecretKey] used while encrypting, this
 | 
			
		||||
     * authenticating the sender party cryptographically. This key could be used to encrypt
 | 
			
		||||
     * the response to be visible to the sender only; the sender, providing it kept his secret key,
 | 
			
		||||
     * could decrypt it.
 | 
			
		||||
     */
 | 
			
		||||
    @Transient
 | 
			
		||||
    var authorisedByKey: PublicKey? = null
 | 
			
		||||
    var authorisedByKey: EncryptingPublicKey? = null
 | 
			
		||||
        protected set
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
@ -193,7 +203,7 @@ sealed class Container {
 | 
			
		||||
                    kotlin.runCatching { k.decrypt(encryptedMessage) }.getOrNull()?.let {
 | 
			
		||||
                        decryptedData = it
 | 
			
		||||
                        decryptedWithKey = k
 | 
			
		||||
                        if( k is SecretKey) {
 | 
			
		||||
                        if(k is DecryptingSecretKey) {
 | 
			
		||||
                            authorisedByKey = Asymmetric.Message.decode(encryptedMessage).senderPublicKey
 | 
			
		||||
                        }
 | 
			
		||||
                        return it
 | 
			
		||||
@ -216,7 +226,7 @@ sealed class Container {
 | 
			
		||||
                    // otherwise, we don't know the encryption key and will try to derive it
 | 
			
		||||
                    // from the decryption key:
 | 
			
		||||
                    when (val k = decryptedWithKey!!) {
 | 
			
		||||
                        is SecretKey -> {
 | 
			
		||||
                        is DecryptingSecretKey -> {
 | 
			
		||||
                            key(k.publicKey)
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
@ -259,12 +269,12 @@ sealed class Container {
 | 
			
		||||
            constructor(key: EncryptingKey, encodeMainKey: UByteArray) :
 | 
			
		||||
                    this(key.id, key.encrypt(encodeMainKey))
 | 
			
		||||
 | 
			
		||||
            constructor(sender: SecretKey?, recipient: PublicKey, encodeMainKey: UByteArray) :
 | 
			
		||||
            constructor(sender: DecryptingSecretKey?, recipient: EncryptingPublicKey, encodeMainKey: UByteArray) :
 | 
			
		||||
                    this(
 | 
			
		||||
                        recipient.id,
 | 
			
		||||
                        recipient.encryptMessage(
 | 
			
		||||
                            encodeMainKey,
 | 
			
		||||
                            senderKey = sender ?: SecretKey.new(),
 | 
			
		||||
                            senderKey = sender ?: DecryptingSecretKey.new(),
 | 
			
		||||
                        ).encoded
 | 
			
		||||
                    )
 | 
			
		||||
        }
 | 
			
		||||
@ -294,7 +304,7 @@ sealed class Container {
 | 
			
		||||
                                throw InvalidContainerException()
 | 
			
		||||
                            decryptedWithKeyId = key.id
 | 
			
		||||
                            mainKey = k
 | 
			
		||||
                            if( key is SecretKey) {
 | 
			
		||||
                            if(key is DecryptingSecretKey) {
 | 
			
		||||
                                authorisedByKey = Asymmetric.Message.decode(encryptedKey.cipherData).senderPublicKey
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
@ -358,8 +368,8 @@ sealed class Container {
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            /**
 | 
			
		||||
             * Add one or more [SecretKey] as sender authority coupled with [PublicKey] as
 | 
			
		||||
             * a recipient. This is faster than anonymous usage of [PublicKey] only
 | 
			
		||||
             * Add one or more [DecryptingSecretKey] as sender authority coupled with [EncryptingPublicKey] as
 | 
			
		||||
             * a recipient. This is faster than anonymous usage of [EncryptingPublicKey] only
 | 
			
		||||
             */
 | 
			
		||||
            fun key(vararg pairs: AsymmetricEncryptionPair) {
 | 
			
		||||
                keyPairs.addAll(pairs)
 | 
			
		||||
@ -368,7 +378,7 @@ sealed class Container {
 | 
			
		||||
            /**
 | 
			
		||||
             * Add one or more public keys as recipients. This is slower than using pairs of sender -> recipient.
 | 
			
		||||
             */
 | 
			
		||||
            fun key(vararg publicKeys: PublicKey) {
 | 
			
		||||
            fun key(vararg publicKeys: EncryptingPublicKey) {
 | 
			
		||||
                keyPairs.addAll(publicKeys.map { null to it })
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
@ -429,7 +439,7 @@ sealed class Container {
 | 
			
		||||
                Single(
 | 
			
		||||
                    pk.id, pk.encryptMessage(
 | 
			
		||||
                        plainData,
 | 
			
		||||
                        senderKey = sk ?: SecretKey.new(),
 | 
			
		||||
                        senderKey = sk ?: DecryptingSecretKey.new(),
 | 
			
		||||
                        randomFill = fillRange
 | 
			
		||||
                    ).encoded,
 | 
			
		||||
                    plainData,
 | 
			
		||||
 | 
			
		||||
@ -1,3 +1,13 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2025. Sergey S. Chernov - All Rights Reserved
 | 
			
		||||
 *
 | 
			
		||||
 *  You may use, distribute and modify this code under the
 | 
			
		||||
 * terms of the private license, which you must obtain from the author
 | 
			
		||||
 *
 | 
			
		||||
 * To obtain the license, contact the author: https://t.me/real_sergeych or email to
 | 
			
		||||
 * real dot sergeych at gmail.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package net.sergeych.crypto2
 | 
			
		||||
 | 
			
		||||
import net.sergeych.bintools.CRC
 | 
			
		||||
 | 
			
		||||
@ -1,3 +1,13 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2025. Sergey S. Chernov - All Rights Reserved
 | 
			
		||||
 *
 | 
			
		||||
 *  You may use, distribute and modify this code under the
 | 
			
		||||
 * terms of the private license, which you must obtain from the author
 | 
			
		||||
 *
 | 
			
		||||
 * To obtain the license, contact the author: https://t.me/real_sergeych or email to
 | 
			
		||||
 * real dot sergeych at gmail.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package net.sergeych.crypto2
 | 
			
		||||
 | 
			
		||||
import com.ionspin.kotlin.crypto.util.decodeFromUByteArray
 | 
			
		||||
@ -8,7 +18,7 @@ import net.sergeych.crypto2.SymmetricKey.WithNonce
 | 
			
		||||
/**
 | 
			
		||||
 * Some key able to perform decrypting. It is not serializable by purpose, as not all such
 | 
			
		||||
 * keys are wise to transfer/save. Concrete implementations are, like [SymmetricKey] or
 | 
			
		||||
 * [SecretKey].
 | 
			
		||||
 * [DecryptingSecretKey].
 | 
			
		||||
 */
 | 
			
		||||
interface DecryptingKey : NonceBased, KeyInstance {
 | 
			
		||||
    /**
 | 
			
		||||
 | 
			
		||||
@ -1,3 +1,13 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2025. Sergey S. Chernov - All Rights Reserved
 | 
			
		||||
 *
 | 
			
		||||
 *  You may use, distribute and modify this code under the
 | 
			
		||||
 * terms of the private license, which you must obtain from the author
 | 
			
		||||
 *
 | 
			
		||||
 * To obtain the license, contact the author: https://t.me/real_sergeych or email to
 | 
			
		||||
 * real dot sergeych at gmail.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package net.sergeych.crypto2
 | 
			
		||||
 | 
			
		||||
import com.ionspin.kotlin.crypto.util.encodeToUByteArray
 | 
			
		||||
 | 
			
		||||
@ -1,3 +1,13 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2025. Sergey S. Chernov - All Rights Reserved
 | 
			
		||||
 *
 | 
			
		||||
 *  You may use, distribute and modify this code under the
 | 
			
		||||
 * terms of the private license, which you must obtain from the author
 | 
			
		||||
 *
 | 
			
		||||
 * To obtain the license, contact the author: https://t.me/real_sergeych or email to
 | 
			
		||||
 * real dot sergeych at gmail.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package net.sergeych.crypto2
 | 
			
		||||
 | 
			
		||||
import com.ionspin.kotlin.crypto.generichash.GenericHash
 | 
			
		||||
 | 
			
		||||
@ -1,3 +1,13 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2025. Sergey S. Chernov - All Rights Reserved
 | 
			
		||||
 *
 | 
			
		||||
 *  You may use, distribute and modify this code under the
 | 
			
		||||
 * terms of the private license, which you must obtain from the author
 | 
			
		||||
 *
 | 
			
		||||
 * To obtain the license, contact the author: https://t.me/real_sergeych or email to
 | 
			
		||||
 * real dot sergeych at gmail.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package net.sergeych.crypto2
 | 
			
		||||
 | 
			
		||||
import com.ionspin.kotlin.crypto.LibsodiumInitializer
 | 
			
		||||
 | 
			
		||||
@ -1,3 +1,13 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2025. Sergey S. Chernov - All Rights Reserved
 | 
			
		||||
 *
 | 
			
		||||
 *  You may use, distribute and modify this code under the
 | 
			
		||||
 * terms of the private license, which you must obtain from the author
 | 
			
		||||
 *
 | 
			
		||||
 * To obtain the license, contact the author: https://t.me/real_sergeych or email to
 | 
			
		||||
 * real dot sergeych at gmail.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package net.sergeych.crypto2
 | 
			
		||||
 | 
			
		||||
import kotlinx.serialization.Serializable
 | 
			
		||||
@ -10,7 +20,7 @@ import kotlinx.serialization.Serializable
 | 
			
		||||
 * Important. `KeyId` of matching keys are the same, so you can use it to identify
 | 
			
		||||
 * and find matching keys in the [UniversalRing], etc. For example:
 | 
			
		||||
 *
 | 
			
		||||
 * - [SecretKey] and [PublicKey] from the same pair have the same `KeyId`, thus the former
 | 
			
		||||
 * - [DecryptingSecretKey] and [EncryptingPublicKey] from the same pair have the same `KeyId`, thus the former
 | 
			
		||||
 *   can decrypt what was encrypted with the latter.
 | 
			
		||||
 *
 | 
			
		||||
 * - [SigningSecretKey] and corresponding [VerifyingKey] have the same `KeyId`. Use it to pick a proper key for
 | 
			
		||||
@ -18,7 +28,7 @@ import kotlinx.serialization.Serializable
 | 
			
		||||
 *
 | 
			
		||||
 * See [PBKD.Params.deriveKey] for deriving keys from id.
 | 
			
		||||
 *
 | 
			
		||||
 * See [id], and [BinaryId] class for more. Note that for [PublicKey] and [VerifyingPublicKey] [BinaryId.asPublicKey]
 | 
			
		||||
 * See [id], and [BinaryId] class for more. Note that for [EncryptingPublicKey] and [VerifyingPublicKey] [BinaryId.asPublicKey]
 | 
			
		||||
 * and [BinaryId.asVerifyingKey] restore actual keys, providing [BinaryId.magic] has proper value, see [KeysmagicNumber]]
 | 
			
		||||
 *
 | 
			
		||||
 * @param id actual id used in equality test amd hash code generation. `Id` of the matching keys is the same.
 | 
			
		||||
 | 
			
		||||
@ -1,3 +1,13 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2025. Sergey S. Chernov - All Rights Reserved
 | 
			
		||||
 *
 | 
			
		||||
 *  You may use, distribute and modify this code under the
 | 
			
		||||
 * terms of the private license, which you must obtain from the author
 | 
			
		||||
 *
 | 
			
		||||
 * To obtain the license, contact the author: https://t.me/real_sergeych or email to
 | 
			
		||||
 * real dot sergeych at gmail.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package net.sergeych.crypto2
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 | 
			
		||||
@ -1,3 +1,13 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2025. Sergey S. Chernov - All Rights Reserved
 | 
			
		||||
 *
 | 
			
		||||
 *  You may use, distribute and modify this code under the
 | 
			
		||||
 * terms of the private license, which you must obtain from the author
 | 
			
		||||
 *
 | 
			
		||||
 * To obtain the license, contact the author: https://t.me/real_sergeych or email to
 | 
			
		||||
 * real dot sergeych at gmail.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package net.sergeych.crypto2
 | 
			
		||||
 | 
			
		||||
enum class KeysmagicNumber(val label: String) {
 | 
			
		||||
 | 
			
		||||
@ -1,3 +1,13 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2025. Sergey S. Chernov - All Rights Reserved
 | 
			
		||||
 *
 | 
			
		||||
 *  You may use, distribute and modify this code under the
 | 
			
		||||
 * terms of the private license, which you must obtain from the author
 | 
			
		||||
 *
 | 
			
		||||
 * To obtain the license, contact the author: https://t.me/real_sergeych or email to
 | 
			
		||||
 * real dot sergeych at gmail.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package net.sergeych.crypto2
 | 
			
		||||
 | 
			
		||||
import kotlinx.serialization.SerialName
 | 
			
		||||
 | 
			
		||||
@ -1,3 +1,13 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2025. Sergey S. Chernov - All Rights Reserved
 | 
			
		||||
 *
 | 
			
		||||
 *  You may use, distribute and modify this code under the
 | 
			
		||||
 * terms of the private license, which you must obtain from the author
 | 
			
		||||
 *
 | 
			
		||||
 * To obtain the license, contact the author: https://t.me/real_sergeych or email to
 | 
			
		||||
 * real dot sergeych at gmail.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package net.sergeych.crypto2
 | 
			
		||||
 | 
			
		||||
interface NonceBased {
 | 
			
		||||
 | 
			
		||||
@ -1,3 +1,13 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2025. Sergey S. Chernov - All Rights Reserved
 | 
			
		||||
 *
 | 
			
		||||
 *  You may use, distribute and modify this code under the
 | 
			
		||||
 * terms of the private license, which you must obtain from the author
 | 
			
		||||
 *
 | 
			
		||||
 * To obtain the license, contact the author: https://t.me/real_sergeych or email to
 | 
			
		||||
 * real dot sergeych at gmail.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package net.sergeych.crypto2
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 | 
			
		||||
@ -1,3 +1,13 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2025. Sergey S. Chernov - All Rights Reserved
 | 
			
		||||
 *
 | 
			
		||||
 *  You may use, distribute and modify this code under the
 | 
			
		||||
 * terms of the private license, which you must obtain from the author
 | 
			
		||||
 *
 | 
			
		||||
 * To obtain the license, contact the author: https://t.me/real_sergeych or email to
 | 
			
		||||
 * real dot sergeych at gmail.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package net.sergeych.crypto2
 | 
			
		||||
 | 
			
		||||
import com.ionspin.kotlin.crypto.util.encodeToUByteArray
 | 
			
		||||
 | 
			
		||||
@ -1,3 +1,13 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2025. Sergey S. Chernov - All Rights Reserved
 | 
			
		||||
 *
 | 
			
		||||
 *  You may use, distribute and modify this code under the
 | 
			
		||||
 * terms of the private license, which you must obtain from the author
 | 
			
		||||
 *
 | 
			
		||||
 * To obtain the license, contact the author: https://t.me/real_sergeych or email to
 | 
			
		||||
 * real dot sergeych at gmail.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package net.sergeych.crypto2
 | 
			
		||||
 | 
			
		||||
import kotlinx.serialization.SerialName
 | 
			
		||||
@ -7,20 +17,22 @@ import net.sergeych.bipack.decodeFromBipack
 | 
			
		||||
import net.sergeych.crypto2.VerifyingPublicKey.Companion.toString
 | 
			
		||||
import net.sergeych.mp_tools.decodeBase64Url
 | 
			
		||||
 | 
			
		||||
@Deprecated("Use EncryptingPublicKey",ReplaceWith("EncryptingPublicKey"))
 | 
			
		||||
typealias PublicKey = EncryptingPublicKey
 | 
			
		||||
/**
 | 
			
		||||
 * The public for public-key encryption. It encrypts messages that can only be decrypted with corresponding
 | 
			
		||||
 * [SecretKey].
 | 
			
		||||
 * [DecryptingSecretKey].
 | 
			
		||||
 */
 | 
			
		||||
@Serializable
 | 
			
		||||
@SerialName("encp")
 | 
			
		||||
class PublicKey(override val keyBytes: UByteArray) : UniversalKey(), EncryptingKey {
 | 
			
		||||
class EncryptingPublicKey(override val keyBytes: UByteArray) : UniversalKey(), EncryptingKey {
 | 
			
		||||
 | 
			
		||||
    override val magic: KeysmagicNumber = KeysmagicNumber.defaultAssymmetric
 | 
			
		||||
    @Transient
 | 
			
		||||
    override val label: String = "pub"
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Create an anonymous message that could be decrypted only with the [SecretKey] that corresponds this.
 | 
			
		||||
     * Create an anonymous message that could be decrypted only with the [DecryptingSecretKey] that corresponds this.
 | 
			
		||||
     * Anonymous message uses one-time secret key, the public part of which is included into the
 | 
			
		||||
     * [Asymmetric.Message], so the sender could not be identified.
 | 
			
		||||
     *
 | 
			
		||||
@ -57,18 +69,18 @@ class PublicKey(override val keyBytes: UByteArray) : UniversalKey(), EncryptingK
 | 
			
		||||
    fun encryptMessage(
 | 
			
		||||
        plainData: UByteArray,
 | 
			
		||||
        nonce: UByteArray = randomNonce(),
 | 
			
		||||
        senderKey: SecretKey = newSecretKey(),
 | 
			
		||||
        senderKey: DecryptingSecretKey = newSecretKey(),
 | 
			
		||||
        randomFill: IntRange? = null,
 | 
			
		||||
    ) = Asymmetric.createMessage(senderKey, this, WithFill.encode(plainData, randomFill), nonce)
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Encrypt message using the specified secret key as sender authentication. Recipient, the party having
 | 
			
		||||
     * [SecretKey] corresponding to this one, will be able to decrypt the message and be sure that [senderKey]
 | 
			
		||||
     * [DecryptingSecretKey] corresponding to this one, will be able to decrypt the message and be sure that [senderKey]
 | 
			
		||||
     * was the author and the message was not altered.
 | 
			
		||||
     */
 | 
			
		||||
    fun encryptMessage(
 | 
			
		||||
        plainData: UByteArray,
 | 
			
		||||
        senderKey: SecretKey,
 | 
			
		||||
        senderKey: DecryptingSecretKey,
 | 
			
		||||
        randomFill: IntRange? = null,
 | 
			
		||||
    ): Asymmetric.Message =
 | 
			
		||||
        Asymmetric.createMessage(senderKey, this, WithFill.encode(plainData, randomFill))
 | 
			
		||||
@ -81,12 +93,12 @@ class PublicKey(override val keyBytes: UByteArray) : UniversalKey(), EncryptingK
 | 
			
		||||
         * possible)
 | 
			
		||||
         * @throws IllegalArgumentException the public key isn't recognized
 | 
			
		||||
         */
 | 
			
		||||
        fun parse(text: String): PublicKey {
 | 
			
		||||
        fun parse(text: String): EncryptingPublicKey {
 | 
			
		||||
            val s = text.trim()
 | 
			
		||||
 | 
			
		||||
            fun parseId(t: String): PublicKey{
 | 
			
		||||
            fun parseId(t: String): EncryptingPublicKey {
 | 
			
		||||
                val id = BinaryId.restoreFromString(t)
 | 
			
		||||
                if( id.magic != KeysmagicNumber.defaultAssymmetric.ordinal)
 | 
			
		||||
                if (id.magic != KeysmagicNumber.defaultAssymmetric.ordinal)
 | 
			
		||||
                    throw IllegalArgumentException("invalid magick ${id.magic} for PublicKey")
 | 
			
		||||
                return id.asPublicKey
 | 
			
		||||
            }
 | 
			
		||||
@ -100,10 +112,10 @@ class PublicKey(override val keyBytes: UByteArray) : UniversalKey(), EncryptingK
 | 
			
		||||
                    // consider it is serialized key in base64 format
 | 
			
		||||
                    val data = s.decodeBase64Url().asUByteArray()
 | 
			
		||||
                    if (data.size == 32)
 | 
			
		||||
                        PublicKey(data)
 | 
			
		||||
                        EncryptingPublicKey(data)
 | 
			
		||||
                    else {
 | 
			
		||||
                        runCatching { data.decodeFromBipack<PublicKey>() }.getOrNull()
 | 
			
		||||
                            ?: kotlin.runCatching { data.decodeFromBipack<UniversalKey>() as PublicKey }
 | 
			
		||||
                        runCatching { data.decodeFromBipack<EncryptingPublicKey>() }.getOrNull()
 | 
			
		||||
                            ?: kotlin.runCatching { data.decodeFromBipack<UniversalKey>() as EncryptingPublicKey }
 | 
			
		||||
                                .getOrElse { throw IllegalArgumentException("can't parse verifying key") }
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
@ -1,3 +1,13 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2025. Sergey S. Chernov - All Rights Reserved
 | 
			
		||||
 *
 | 
			
		||||
 *  You may use, distribute and modify this code under the
 | 
			
		||||
 * terms of the private license, which you must obtain from the author
 | 
			
		||||
 *
 | 
			
		||||
 * To obtain the license, contact the author: https://t.me/real_sergeych or email to
 | 
			
		||||
 * real dot sergeych at gmail.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package net.sergeych.crypto2
 | 
			
		||||
 | 
			
		||||
import com.ionspin.kotlin.crypto.keyexchange.KeyExchange
 | 
			
		||||
@ -10,7 +20,7 @@ import net.sergeych.crypto2.SafeKeyExchange.SessionKey
 | 
			
		||||
 * Usage:
 | 
			
		||||
 *
 | 
			
		||||
 * 1. Create [SafeKeyExchange] on both server and client sides
 | 
			
		||||
 * 2. Exchange [publicKey] instances
 | 
			
		||||
 * 2. Exchange [EncryptingPublicKey] instances
 | 
			
		||||
 * 3. Create [serverSessionKey] and [clientSessionKey] respectively
 | 
			
		||||
 * 4. Use [SessionKey.sendingKey] and [SessionKey.receivingKey] to send and receive encrypted data.
 | 
			
		||||
 *
 | 
			
		||||
@ -20,7 +30,7 @@ import net.sergeych.crypto2.SafeKeyExchange.SessionKey
 | 
			
		||||
 *   instances as often as performance considerations allow.
 | 
			
		||||
 * - while it is possible to generate several keys "ahead", the care should be taken when storing them,
 | 
			
		||||
 *   encrypt it with some other key to maintain safety.
 | 
			
		||||
 * - do not use [publicKey] for anything but creating session keys.
 | 
			
		||||
 * - do not use [EncryptingPublicKey] for anything but creating session keys.
 | 
			
		||||
 */
 | 
			
		||||
class SafeKeyExchange {
 | 
			
		||||
    private val pair = KeyExchange.keypair()
 | 
			
		||||
 | 
			
		||||
@ -1,3 +1,13 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2025. Sergey S. Chernov - All Rights Reserved
 | 
			
		||||
 *
 | 
			
		||||
 *  You may use, distribute and modify this code under the
 | 
			
		||||
 * terms of the private license, which you must obtain from the author
 | 
			
		||||
 *
 | 
			
		||||
 * To obtain the license, contact the author: https://t.me/real_sergeych or email to
 | 
			
		||||
 * real dot sergeych at gmail.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package net.sergeych.crypto2
 | 
			
		||||
 | 
			
		||||
import kotlinx.datetime.Instant
 | 
			
		||||
@ -6,6 +16,7 @@ import net.sergeych.bipack.BipackEncoder
 | 
			
		||||
import net.sergeych.bipack.decodeFromBipack
 | 
			
		||||
import net.sergeych.crypto2.Seal.Companion.create
 | 
			
		||||
import net.sergeych.utools.now
 | 
			
		||||
import kotlin.time.Duration.Companion.seconds
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Extended public-key signature.
 | 
			
		||||
@ -67,7 +78,7 @@ class Seal(
 | 
			
		||||
     */
 | 
			
		||||
    fun verify(message: UByteArray) {
 | 
			
		||||
        val n = now()
 | 
			
		||||
        if (createdAt > n) throw IllegalSignatureException("signature's timestamp in the future")
 | 
			
		||||
        if (createdAt - 45.seconds > n) throw IllegalSignatureException("signature's timestamp in the future: $createdAt / $n")
 | 
			
		||||
        expiresAt?.let {
 | 
			
		||||
            if (n >= it) throw ExpiredSignatureException("signature expired at $it")
 | 
			
		||||
        }
 | 
			
		||||
@ -98,7 +109,7 @@ class Seal(
 | 
			
		||||
         * to check the authenticity of the arbitrary [message] using a public key, [VerifyingPublicKey]
 | 
			
		||||
         * instance, using public-key signing algorithms.
 | 
			
		||||
         *
 | 
			
		||||
         * Unlike a regular binary signature, Seal contains the signer's [publicKey], and also
 | 
			
		||||
         * Unlike a regular binary signature, Seal contains the signer's [EncryptingPublicKey], and also
 | 
			
		||||
         * [createdAt] and [expiresAt] fields which are also signed and are guaranteed to be non-tampered
 | 
			
		||||
         * if the [isValid] returns true (or [verify] does not throw). See [isExpired].
 | 
			
		||||
         *
 | 
			
		||||
 | 
			
		||||
@ -1,3 +1,13 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2025. Sergey S. Chernov - All Rights Reserved
 | 
			
		||||
 *
 | 
			
		||||
 *  You may use, distribute and modify this code under the
 | 
			
		||||
 * terms of the private license, which you must obtain from the author
 | 
			
		||||
 *
 | 
			
		||||
 * To obtain the license, contact the author: https://t.me/real_sergeych or email to
 | 
			
		||||
 * real dot sergeych at gmail.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package net.sergeych.crypto2
 | 
			
		||||
 | 
			
		||||
import kotlinx.datetime.Instant
 | 
			
		||||
@ -82,6 +92,7 @@ class SealedBox(
 | 
			
		||||
    /**
 | 
			
		||||
     * Unpack bipack-encoded payload
 | 
			
		||||
     */
 | 
			
		||||
    @Suppress("unused")
 | 
			
		||||
    inline fun <reified T>unpack(): T = BipackDecoder.decode(message)
 | 
			
		||||
 | 
			
		||||
    init {
 | 
			
		||||
 | 
			
		||||
@ -1,3 +1,13 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2025. Sergey S. Chernov - All Rights Reserved
 | 
			
		||||
 *
 | 
			
		||||
 *  You may use, distribute and modify this code under the
 | 
			
		||||
 * terms of the private license, which you must obtain from the author
 | 
			
		||||
 *
 | 
			
		||||
 * To obtain the license, contact the author: https://t.me/real_sergeych or email to
 | 
			
		||||
 * real dot sergeych at gmail.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package net.sergeych.crypto2
 | 
			
		||||
 | 
			
		||||
import com.ionspin.kotlin.crypto.box.Box
 | 
			
		||||
@ -6,24 +16,28 @@ import kotlinx.serialization.SerialName
 | 
			
		||||
import kotlinx.serialization.Serializable
 | 
			
		||||
import kotlinx.serialization.Transient
 | 
			
		||||
 | 
			
		||||
@Deprecated("Use DecryptingSecretKey instead",ReplaceWith("DecryptingSecretKey"))
 | 
			
		||||
typealias SecretKey = DecryptingSecretKey
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * The secret key used in public-key encryption; it is used to _decrypt_ data encrypted with its
 | 
			
		||||
 * public counterpart, see [publicKey].
 | 
			
		||||
 * public counterpart, see [EncryptingPublicKey].
 | 
			
		||||
 */
 | 
			
		||||
@Serializable
 | 
			
		||||
@SerialName("encs")
 | 
			
		||||
class SecretKey(
 | 
			
		||||
class DecryptingSecretKey(
 | 
			
		||||
    override val keyBytes: UByteArray,
 | 
			
		||||
    @Transient
 | 
			
		||||
    val _cachedPublicKey: PublicKey? = null,
 | 
			
		||||
    val _cachedPublicKey: EncryptingPublicKey? = null,
 | 
			
		||||
) : DecryptingKey, UniversalKey() {
 | 
			
		||||
 | 
			
		||||
    @Transient
 | 
			
		||||
    override val label: String = "sec"
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Decrypt with authentication checks the message which must have [Asymmetric.Message.senderPublicKey] set.
 | 
			
		||||
     * Use [decryptWithSenderKey] otherwise. Note that the authenticated encryption is always use, even if
 | 
			
		||||
     * the [PublicKey.encryptAnonymousMessage] was used to create a message, if it is successfully decrypted,
 | 
			
		||||
     * the [EncryptingPublicKey.encryptAnonymousMessage] was used to create a message, if it is successfully decrypted,
 | 
			
		||||
     * it is guaranteed that the message was not altered after creation.
 | 
			
		||||
     *
 | 
			
		||||
     * @throws DecryptionFailedException If the message is tampered (changed after creation) or was not intended for us,
 | 
			
		||||
@ -35,20 +49,20 @@ class SecretKey(
 | 
			
		||||
     * Decrypt using [senderPublicKey] as a sender key (overriding the [Asymmetric.Message.senderPublicKey] if set).
 | 
			
		||||
     * See [decrypt] for more.
 | 
			
		||||
     */
 | 
			
		||||
    fun decryptWithSenderKey(message: Asymmetric.Message, senderPublicKey: PublicKey): UByteArray =
 | 
			
		||||
    fun decryptWithSenderKey(message: Asymmetric.Message, senderPublicKey: EncryptingPublicKey): UByteArray =
 | 
			
		||||
        message.decryptWithSenderKey(senderPublicKey, this)
 | 
			
		||||
 | 
			
		||||
    @Transient
 | 
			
		||||
    private var cachedPublicKey: PublicKey? = _cachedPublicKey
 | 
			
		||||
    private var cachedPublicKey: EncryptingPublicKey? = _cachedPublicKey
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * The corresponding public key
 | 
			
		||||
     */
 | 
			
		||||
    val publicKey: PublicKey by lazy {
 | 
			
		||||
    val publicKey: EncryptingPublicKey by lazy {
 | 
			
		||||
        if (cachedPublicKey != null)
 | 
			
		||||
            cachedPublicKey!!
 | 
			
		||||
        else
 | 
			
		||||
            PublicKey(ScalarMultiplication.scalarMultiplicationBase(keyBytes))
 | 
			
		||||
            EncryptingPublicKey(ScalarMultiplication.scalarMultiplicationBase(keyBytes))
 | 
			
		||||
                .also { cachedPublicKey = it }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -71,18 +85,18 @@ class SecretKey(
 | 
			
		||||
        get() = 0
 | 
			
		||||
 | 
			
		||||
    companion object {
 | 
			
		||||
        data class KeyPair(val secretKey: SecretKey, val publicKey: PublicKey)
 | 
			
		||||
        data class KeyPair(val secretKey: DecryptingSecretKey, val publicKey: EncryptingPublicKey)
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Generate a new random pair of public and secret keys.
 | 
			
		||||
         */
 | 
			
		||||
        fun generateKeys(): KeyPair {
 | 
			
		||||
            val p = Box.keypair()
 | 
			
		||||
            val pk = PublicKey(p.publicKey)
 | 
			
		||||
            return KeyPair(SecretKey(p.secretKey, pk), pk)
 | 
			
		||||
            val pk = EncryptingPublicKey(p.publicKey)
 | 
			
		||||
            return KeyPair(DecryptingSecretKey(p.secretKey, pk), pk)
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        fun new(): SecretKey = generateKeys().secretKey
 | 
			
		||||
        fun new(): DecryptingSecretKey = generateKeys().secretKey
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -1,3 +1,13 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2025. Sergey S. Chernov - All Rights Reserved
 | 
			
		||||
 *
 | 
			
		||||
 *  You may use, distribute and modify this code under the
 | 
			
		||||
 * terms of the private license, which you must obtain from the author
 | 
			
		||||
 *
 | 
			
		||||
 * To obtain the license, contact the author: https://t.me/real_sergeych or email to
 | 
			
		||||
 * real dot sergeych at gmail.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package net.sergeych.crypto2
 | 
			
		||||
 | 
			
		||||
import kotlinx.datetime.Instant
 | 
			
		||||
 | 
			
		||||
@ -1,3 +1,13 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2025. Sergey S. Chernov - All Rights Reserved
 | 
			
		||||
 *
 | 
			
		||||
 *  You may use, distribute and modify this code under the
 | 
			
		||||
 * terms of the private license, which you must obtain from the author
 | 
			
		||||
 *
 | 
			
		||||
 * To obtain the license, contact the author: https://t.me/real_sergeych or email to
 | 
			
		||||
 * real dot sergeych at gmail.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package net.sergeych.crypto2
 | 
			
		||||
 | 
			
		||||
import com.ionspin.kotlin.crypto.signature.Signature
 | 
			
		||||
 | 
			
		||||
@ -1,3 +1,13 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2025. Sergey S. Chernov - All Rights Reserved
 | 
			
		||||
 *
 | 
			
		||||
 *  You may use, distribute and modify this code under the
 | 
			
		||||
 * terms of the private license, which you must obtain from the author
 | 
			
		||||
 *
 | 
			
		||||
 * To obtain the license, contact the author: https://t.me/real_sergeych or email to
 | 
			
		||||
 * real dot sergeych at gmail.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package net.sergeych.crypto2
 | 
			
		||||
 | 
			
		||||
import com.ionspin.kotlin.crypto.secretbox.SecretBox
 | 
			
		||||
 | 
			
		||||
@ -1,3 +1,13 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2025. Sergey S. Chernov - All Rights Reserved
 | 
			
		||||
 *
 | 
			
		||||
 *  You may use, distribute and modify this code under the
 | 
			
		||||
 * terms of the private license, which you must obtain from the author
 | 
			
		||||
 *
 | 
			
		||||
 * To obtain the license, contact the author: https://t.me/real_sergeych or email to
 | 
			
		||||
 * real dot sergeych at gmail.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package net.sergeych.crypto2
 | 
			
		||||
 | 
			
		||||
import kotlinx.serialization.Serializable
 | 
			
		||||
@ -17,7 +27,7 @@ sealed class UniversalKey : KeyInstance {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Key ID positively identify key from the point of view of _decrypting or verifying_. So matching [VerifyingKey]
 | 
			
		||||
     * and [SigningKey] will have the same id, same as matching [PublicKey] and [SecretKey].
 | 
			
		||||
     * and [SigningKey] will have the same id, same as matching [EncryptingPublicKey] and [DecryptingSecretKey].
 | 
			
		||||
     *
 | 
			
		||||
     * KeyId is based on [BinaryId] which includes checksum (crc8) and magick number for additional security,
 | 
			
		||||
     * see [KeysmagicNumber].
 | 
			
		||||
@ -43,7 +53,7 @@ sealed class UniversalKey : KeyInstance {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    companion object {
 | 
			
		||||
        fun newSecretKey() = SecretKey.new()
 | 
			
		||||
        fun newSecretKey() = DecryptingSecretKey.new()
 | 
			
		||||
        fun newSigningKey() = SigningSecretKey.new()
 | 
			
		||||
 | 
			
		||||
        @Suppress("unused")
 | 
			
		||||
@ -57,7 +67,7 @@ sealed class UniversalKey : KeyInstance {
 | 
			
		||||
            val s = text.trim()
 | 
			
		||||
            return when {
 | 
			
		||||
                s.startsWith("\uD83D\uDDDDpub#") || s.startsWith("pub#") ->
 | 
			
		||||
                    PublicKey.parse(s)
 | 
			
		||||
                    EncryptingPublicKey.parse(s)
 | 
			
		||||
                s.startsWith("\uD83D\uDDDDver#") || s.startsWith("ver#") ->
 | 
			
		||||
                    VerifyingPublicKey.parse(s)
 | 
			
		||||
                else -> {
 | 
			
		||||
 | 
			
		||||
@ -1,3 +1,13 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2025. Sergey S. Chernov - All Rights Reserved
 | 
			
		||||
 *
 | 
			
		||||
 *  You may use, distribute and modify this code under the
 | 
			
		||||
 * terms of the private license, which you must obtain from the author
 | 
			
		||||
 *
 | 
			
		||||
 * To obtain the license, contact the author: https://t.me/real_sergeych or email to
 | 
			
		||||
 * real dot sergeych at gmail.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package net.sergeych.crypto2
 | 
			
		||||
 | 
			
		||||
import kotlinx.serialization.SerialName
 | 
			
		||||
@ -14,7 +24,7 @@ import kotlinx.serialization.Transient
 | 
			
		||||
@SerialName("uprv")
 | 
			
		||||
class UniversalPrivateKey(
 | 
			
		||||
    val signingKey: SigningSecretKey,
 | 
			
		||||
    val decryptingKey: SecretKey
 | 
			
		||||
    val decryptingKey: DecryptingSecretKey
 | 
			
		||||
) : UniversalKey(), DecryptingKey by decryptingKey, SigningKey by signingKey {
 | 
			
		||||
 | 
			
		||||
    override val keyBytes by lazy { signingKey.keyBytes + decryptingKey.keyBytes }
 | 
			
		||||
@ -42,6 +52,6 @@ class UniversalPrivateKey(
 | 
			
		||||
         * Generate 2 new random keys (4 key pairs under the hood) to securely signd and
 | 
			
		||||
         * decrypt data.
 | 
			
		||||
         */
 | 
			
		||||
        fun new() = UniversalPrivateKey(SigningSecretKey.new(), SecretKey.new())
 | 
			
		||||
        fun new() = UniversalPrivateKey(SigningSecretKey.new(), DecryptingSecretKey.new())
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -1,3 +1,13 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2025. Sergey S. Chernov - All Rights Reserved
 | 
			
		||||
 *
 | 
			
		||||
 *  You may use, distribute and modify this code under the
 | 
			
		||||
 * terms of the private license, which you must obtain from the author
 | 
			
		||||
 *
 | 
			
		||||
 * To obtain the license, contact the author: https://t.me/real_sergeych or email to
 | 
			
		||||
 * real dot sergeych at gmail.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package net.sergeych.crypto2
 | 
			
		||||
 | 
			
		||||
import kotlinx.serialization.SerialName
 | 
			
		||||
@ -15,7 +25,7 @@ import kotlinx.serialization.Transient
 | 
			
		||||
@SerialName("upub")
 | 
			
		||||
class UniversalPublicKey(
 | 
			
		||||
    val verifyingKey: VerifyingPublicKey,
 | 
			
		||||
    val encryptingKey: PublicKey
 | 
			
		||||
    val encryptingKey: EncryptingPublicKey
 | 
			
		||||
): UniversalKey(), VerifyingKey by verifyingKey, EncryptingKey by encryptingKey{
 | 
			
		||||
 | 
			
		||||
    override val keyBytes by lazy { verifyingKey.keyBytes + encryptingKey.keyBytes }
 | 
			
		||||
 | 
			
		||||
@ -1,3 +1,13 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2025. Sergey S. Chernov - All Rights Reserved
 | 
			
		||||
 *
 | 
			
		||||
 *  You may use, distribute and modify this code under the
 | 
			
		||||
 * terms of the private license, which you must obtain from the author
 | 
			
		||||
 *
 | 
			
		||||
 * To obtain the license, contact the author: https://t.me/real_sergeych or email to
 | 
			
		||||
 * real dot sergeych at gmail.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package net.sergeych.crypto2
 | 
			
		||||
 | 
			
		||||
import kotlinx.serialization.Serializable
 | 
			
		||||
@ -38,7 +48,7 @@ class UniversalRing(
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Find a key of the specified type that matches the id. In general, you require key implementations like
 | 
			
		||||
     * [SecretKey], [PublicKey], [VerifyingPublicKey], [SigningSecretKey] and [SymmetricKey],
 | 
			
		||||
     * [DecryptingSecretKey], [EncryptingPublicKey], [VerifyingPublicKey], [SigningSecretKey] and [SymmetricKey],
 | 
			
		||||
     * or just key interfaces: [EncryptingKey], [DecryptingKey], [SigningKey] and [VerifyingKey].
 | 
			
		||||
     *
 | 
			
		||||
     * Note that key interfaces are not serializable as for now, you should try to cast to a serializable
 | 
			
		||||
 | 
			
		||||
@ -1,3 +1,13 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2025. Sergey S. Chernov - All Rights Reserved
 | 
			
		||||
 *
 | 
			
		||||
 *  You may use, distribute and modify this code under the
 | 
			
		||||
 * terms of the private license, which you must obtain from the author
 | 
			
		||||
 *
 | 
			
		||||
 * To obtain the license, contact the author: https://t.me/real_sergeych or email to
 | 
			
		||||
 * real dot sergeych at gmail.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package net.sergeych.crypto2
 | 
			
		||||
 | 
			
		||||
interface VerifyingKey: KeyInstance {
 | 
			
		||||
 | 
			
		||||
@ -1,3 +1,13 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2025. Sergey S. Chernov - All Rights Reserved
 | 
			
		||||
 *
 | 
			
		||||
 *  You may use, distribute and modify this code under the
 | 
			
		||||
 * terms of the private license, which you must obtain from the author
 | 
			
		||||
 *
 | 
			
		||||
 * To obtain the license, contact the author: https://t.me/real_sergeych or email to
 | 
			
		||||
 * real dot sergeych at gmail.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package net.sergeych.crypto2
 | 
			
		||||
 | 
			
		||||
import com.ionspin.kotlin.crypto.signature.InvalidSignatureException
 | 
			
		||||
 | 
			
		||||
@ -1,3 +1,13 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2025. Sergey S. Chernov - All Rights Reserved
 | 
			
		||||
 *
 | 
			
		||||
 *  You may use, distribute and modify this code under the
 | 
			
		||||
 * terms of the private license, which you must obtain from the author
 | 
			
		||||
 *
 | 
			
		||||
 * To obtain the license, contact the author: https://t.me/real_sergeych or email to
 | 
			
		||||
 * real dot sergeych at gmail.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package net.sergeych.crypto2
 | 
			
		||||
 | 
			
		||||
import kotlinx.serialization.Serializable
 | 
			
		||||
 | 
			
		||||
@ -1,3 +1,13 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2025. Sergey S. Chernov - All Rights Reserved
 | 
			
		||||
 *
 | 
			
		||||
 *  You may use, distribute and modify this code under the
 | 
			
		||||
 * terms of the private license, which you must obtain from the author
 | 
			
		||||
 *
 | 
			
		||||
 * To obtain the license, contact the author: https://t.me/real_sergeych or email to
 | 
			
		||||
 * real dot sergeych at gmail.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package net.sergeych.crypto2
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 | 
			
		||||
@ -1,3 +1,13 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2025. Sergey S. Chernov - All Rights Reserved
 | 
			
		||||
 *
 | 
			
		||||
 *  You may use, distribute and modify this code under the
 | 
			
		||||
 * terms of the private license, which you must obtain from the author
 | 
			
		||||
 *
 | 
			
		||||
 * To obtain the license, contact the author: https://t.me/real_sergeych or email to
 | 
			
		||||
 * real dot sergeych at gmail.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package net.sergeych.crypto2
 | 
			
		||||
 | 
			
		||||
import com.ionspin.kotlin.crypto.pwhash.*
 | 
			
		||||
 | 
			
		||||
@ -1,3 +1,13 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2025. Sergey S. Chernov - All Rights Reserved
 | 
			
		||||
 *
 | 
			
		||||
 *  You may use, distribute and modify this code under the
 | 
			
		||||
 * terms of the private license, which you must obtain from the author
 | 
			
		||||
 *
 | 
			
		||||
 * To obtain the license, contact the author: https://t.me/real_sergeych or email to
 | 
			
		||||
 * real dot sergeych at gmail.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
@file:Suppress("unused")
 | 
			
		||||
 | 
			
		||||
package net.sergeych.crypto2
 | 
			
		||||
 | 
			
		||||
@ -1,3 +1,13 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2025. Sergey S. Chernov - All Rights Reserved
 | 
			
		||||
 *
 | 
			
		||||
 *  You may use, distribute and modify this code under the
 | 
			
		||||
 * terms of the private license, which you must obtain from the author
 | 
			
		||||
 *
 | 
			
		||||
 * To obtain the license, contact the author: https://t.me/real_sergeych or email to
 | 
			
		||||
 * real dot sergeych at gmail.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
@file:Suppress("unused")
 | 
			
		||||
 | 
			
		||||
package net.sergeych.crypto2
 | 
			
		||||
 | 
			
		||||
@ -1,3 +1,13 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2025. Sergey S. Chernov - All Rights Reserved
 | 
			
		||||
 *
 | 
			
		||||
 *  You may use, distribute and modify this code under the
 | 
			
		||||
 * terms of the private license, which you must obtain from the author
 | 
			
		||||
 *
 | 
			
		||||
 * To obtain the license, contact the author: https://t.me/real_sergeych or email to
 | 
			
		||||
 * real dot sergeych at gmail.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package net.sergeych.tools
 | 
			
		||||
 | 
			
		||||
@Suppress("unused")
 | 
			
		||||
 | 
			
		||||
@ -1,3 +1,13 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2025. Sergey S. Chernov - All Rights Reserved
 | 
			
		||||
 *
 | 
			
		||||
 *  You may use, distribute and modify this code under the
 | 
			
		||||
 * terms of the private license, which you must obtain from the author
 | 
			
		||||
 *
 | 
			
		||||
 * To obtain the license, contact the author: https://t.me/real_sergeych or email to
 | 
			
		||||
 * real dot sergeych at gmail.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package net.sergeych.tools
 | 
			
		||||
 | 
			
		||||
import net.sergeych.synctools.ProtectedOp
 | 
			
		||||
@ -5,7 +15,7 @@ import net.sergeych.synctools.invoke
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Multiplatform (JS and battery included) atomically mutable value.
 | 
			
		||||
 * Actual value can be either changed in a block of [mutuate] when
 | 
			
		||||
 * Actual value can be either changed in a block of [mutate] when
 | 
			
		||||
 * new value _depends on the current value_ or use a same [value]
 | 
			
		||||
 * property that is thread-safe where there are threads and just safe
 | 
			
		||||
 * otherwise ;)
 | 
			
		||||
 | 
			
		||||
@ -1,3 +1,13 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2025. Sergey S. Chernov - All Rights Reserved
 | 
			
		||||
 *
 | 
			
		||||
 *  You may use, distribute and modify this code under the
 | 
			
		||||
 * terms of the private license, which you must obtain from the author
 | 
			
		||||
 *
 | 
			
		||||
 * To obtain the license, contact the author: https://t.me/real_sergeych or email to
 | 
			
		||||
 * real dot sergeych at gmail.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
@file:Suppress("unused")
 | 
			
		||||
 | 
			
		||||
package net.sergeych.tools
 | 
			
		||||
 | 
			
		||||
@ -1,3 +1,13 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2025. Sergey S. Chernov - All Rights Reserved
 | 
			
		||||
 *
 | 
			
		||||
 *  You may use, distribute and modify this code under the
 | 
			
		||||
 * terms of the private license, which you must obtain from the author
 | 
			
		||||
 *
 | 
			
		||||
 * To obtain the license, contact the author: https://t.me/real_sergeych or email to
 | 
			
		||||
 * real dot sergeych at gmail.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package net.sergeych.tools
 | 
			
		||||
 | 
			
		||||
import net.sergeych.bipack.BipackDecoder
 | 
			
		||||
 | 
			
		||||
@ -1,3 +1,13 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2025. Sergey S. Chernov - All Rights Reserved
 | 
			
		||||
 *
 | 
			
		||||
 *  You may use, distribute and modify this code under the
 | 
			
		||||
 * terms of the private license, which you must obtain from the author
 | 
			
		||||
 *
 | 
			
		||||
 * To obtain the license, contact the author: https://t.me/real_sergeych or email to
 | 
			
		||||
 * real dot sergeych at gmail.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
@file:Suppress("unused")
 | 
			
		||||
 | 
			
		||||
package net.sergeych.utools
 | 
			
		||||
 | 
			
		||||
@ -1,3 +1,13 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2025. Sergey S. Chernov - All Rights Reserved
 | 
			
		||||
 *
 | 
			
		||||
 *  You may use, distribute and modify this code under the
 | 
			
		||||
 * terms of the private license, which you must obtain from the author
 | 
			
		||||
 *
 | 
			
		||||
 * To obtain the license, contact the author: https://t.me/real_sergeych or email to
 | 
			
		||||
 * real dot sergeych at gmail.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package net.sergeych.utools
 | 
			
		||||
 | 
			
		||||
import kotlinx.serialization.KSerializer
 | 
			
		||||
 | 
			
		||||
@ -1,3 +1,13 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2025. Sergey S. Chernov - All Rights Reserved
 | 
			
		||||
 *
 | 
			
		||||
 *  You may use, distribute and modify this code under the
 | 
			
		||||
 * terms of the private license, which you must obtain from the author
 | 
			
		||||
 *
 | 
			
		||||
 * To obtain the license, contact the author: https://t.me/real_sergeych or email to
 | 
			
		||||
 * real dot sergeych at gmail.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
@file:Suppress("unused")
 | 
			
		||||
 | 
			
		||||
package net.sergeych.utools
 | 
			
		||||
 | 
			
		||||
@ -1,3 +1,13 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2025. Sergey S. Chernov - All Rights Reserved
 | 
			
		||||
 *
 | 
			
		||||
 *  You may use, distribute and modify this code under the
 | 
			
		||||
 * terms of the private license, which you must obtain from the author
 | 
			
		||||
 *
 | 
			
		||||
 * To obtain the license, contact the author: https://t.me/real_sergeych or email to
 | 
			
		||||
 * real dot sergeych at gmail.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package org.komputing.khash.keccak
 | 
			
		||||
 | 
			
		||||
import com.ionspin.kotlin.bignum.integer.BigInteger
 | 
			
		||||
 | 
			
		||||
@ -1,3 +1,13 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2025. Sergey S. Chernov - All Rights Reserved
 | 
			
		||||
 *
 | 
			
		||||
 *  You may use, distribute and modify this code under the
 | 
			
		||||
 * terms of the private license, which you must obtain from the author
 | 
			
		||||
 *
 | 
			
		||||
 * To obtain the license, contact the author: https://t.me/real_sergeych or email to
 | 
			
		||||
 * real dot sergeych at gmail.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
@file:Suppress("unused")
 | 
			
		||||
 | 
			
		||||
package org.komputing.khash.keccak
 | 
			
		||||
 | 
			
		||||
@ -1,3 +1,13 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2025. Sergey S. Chernov - All Rights Reserved
 | 
			
		||||
 *
 | 
			
		||||
 *  You may use, distribute and modify this code under the
 | 
			
		||||
 * terms of the private license, which you must obtain from the author
 | 
			
		||||
 *
 | 
			
		||||
 * To obtain the license, contact the author: https://t.me/real_sergeych or email to
 | 
			
		||||
 * real dot sergeych at gmail.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package org.komputing.khash.keccak.extensions
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 | 
			
		||||
@ -1,3 +1,13 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2025. Sergey S. Chernov - All Rights Reserved
 | 
			
		||||
 *
 | 
			
		||||
 *  You may use, distribute and modify this code under the
 | 
			
		||||
 * terms of the private license, which you must obtain from the author
 | 
			
		||||
 *
 | 
			
		||||
 * To obtain the license, contact the author: https://t.me/real_sergeych or email to
 | 
			
		||||
 * real dot sergeych at gmail.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
@file:Suppress("unused")
 | 
			
		||||
package org.komputing.khash.keccak.extensions
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,5 +1,21 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2025. Sergey S. Chernov - All Rights Reserved
 | 
			
		||||
 *
 | 
			
		||||
 *  You may use, distribute and modify this code under the
 | 
			
		||||
 * terms of the private license, which you must obtain from the author
 | 
			
		||||
 *
 | 
			
		||||
 * To obtain the license, contact the author: https://t.me/real_sergeych or email to
 | 
			
		||||
 * real dot sergeych at gmail.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
import kotlinx.coroutines.test.runTest
 | 
			
		||||
import net.sergeych.bintools.toDump
 | 
			
		||||
import net.sergeych.bipack.BipackEncoder
 | 
			
		||||
import net.sergeych.crypto2.BinaryId
 | 
			
		||||
import net.sergeych.crypto2.ByteChunk
 | 
			
		||||
import net.sergeych.crypto2.initCrypto
 | 
			
		||||
import kotlin.test.Test
 | 
			
		||||
import kotlin.test.assertContentEquals
 | 
			
		||||
import kotlin.test.assertEquals
 | 
			
		||||
 | 
			
		||||
class BinaryIdTest {
 | 
			
		||||
@ -13,4 +29,16 @@ class BinaryIdTest {
 | 
			
		||||
        assertEquals(4, a.id.size)
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    fun testByteChunkSizes() = runTest {
 | 
			
		||||
        initCrypto()
 | 
			
		||||
        val x = ByteChunk.random(3)
 | 
			
		||||
        assertEquals(3, x.data.size)
 | 
			
		||||
        assertEquals(3, x.toByteArray().size)
 | 
			
		||||
        assertEquals(3, x.toUByteArray().size)
 | 
			
		||||
        println(BipackEncoder.encode(x).toDump())
 | 
			
		||||
        assertEquals(4, BipackEncoder.encode(x).size)
 | 
			
		||||
        assertContentEquals(BipackEncoder.encode(x.toByteArray()), BipackEncoder.encode(x))
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -1,3 +1,13 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2025. Sergey S. Chernov - All Rights Reserved
 | 
			
		||||
 *
 | 
			
		||||
 *  You may use, distribute and modify this code under the
 | 
			
		||||
 * terms of the private license, which you must obtain from the author
 | 
			
		||||
 *
 | 
			
		||||
 * To obtain the license, contact the author: https://t.me/real_sergeych or email to
 | 
			
		||||
 * real dot sergeych at gmail.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
import com.ionspin.kotlin.crypto.util.encodeToUByteArray
 | 
			
		||||
import kotlinx.coroutines.test.runTest
 | 
			
		||||
import kotlinx.serialization.encodeToString
 | 
			
		||||
 | 
			
		||||
@ -1,3 +1,13 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2025. Sergey S. Chernov - All Rights Reserved
 | 
			
		||||
 *
 | 
			
		||||
 *  You may use, distribute and modify this code under the
 | 
			
		||||
 * terms of the private license, which you must obtain from the author
 | 
			
		||||
 *
 | 
			
		||||
 * To obtain the license, contact the author: https://t.me/real_sergeych or email to
 | 
			
		||||
 * real dot sergeych at gmail.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
import kotlinx.coroutines.flow.asFlow
 | 
			
		||||
import kotlinx.coroutines.test.runTest
 | 
			
		||||
import kotlinx.datetime.Clock
 | 
			
		||||
 | 
			
		||||
@ -1,3 +1,13 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2025. Sergey S. Chernov - All Rights Reserved
 | 
			
		||||
 *
 | 
			
		||||
 *  You may use, distribute and modify this code under the
 | 
			
		||||
 * terms of the private license, which you must obtain from the author
 | 
			
		||||
 *
 | 
			
		||||
 * To obtain the license, contact the author: https://t.me/real_sergeych or email to
 | 
			
		||||
 * real dot sergeych at gmail.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
import kotlinx.coroutines.test.runTest
 | 
			
		||||
import net.sergeych.crypto2.KDF
 | 
			
		||||
import net.sergeych.crypto2.initCrypto
 | 
			
		||||
 | 
			
		||||
@ -1,3 +1,13 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2025. Sergey S. Chernov - All Rights Reserved
 | 
			
		||||
 *
 | 
			
		||||
 *  You may use, distribute and modify this code under the
 | 
			
		||||
 * terms of the private license, which you must obtain from the author
 | 
			
		||||
 *
 | 
			
		||||
 * To obtain the license, contact the author: https://t.me/real_sergeych or email to
 | 
			
		||||
 * real dot sergeych at gmail.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
import com.ionspin.kotlin.crypto.util.decodeFromUByteArray
 | 
			
		||||
import com.ionspin.kotlin.crypto.util.encodeToUByteArray
 | 
			
		||||
import kotlinx.coroutines.test.runTest
 | 
			
		||||
@ -177,7 +187,7 @@ class KeysTest {
 | 
			
		||||
//        println(sk0.publicKey)
 | 
			
		||||
        val j = Json { prettyPrint = true }
 | 
			
		||||
 | 
			
		||||
        val sk1 = j.decodeFromString<SecretKey>(j.encodeToString(sk0))
 | 
			
		||||
        val sk1 = j.decodeFromString<DecryptingSecretKey>(j.encodeToString(sk0))
 | 
			
		||||
        assertEquals(sk0, sk1)
 | 
			
		||||
        assertEquals(pk0, sk1.publicKey)
 | 
			
		||||
//        println(j.encodeToString(sk1))
 | 
			
		||||
@ -206,9 +216,9 @@ class KeysTest {
 | 
			
		||||
        assertEquals(usy2, usy1)
 | 
			
		||||
        assertFalse { usy1 == usy3 }
 | 
			
		||||
 | 
			
		||||
        val sk1 = SecretKey.new()
 | 
			
		||||
        val sk2 = SecretKey(sk1.keyBytes)
 | 
			
		||||
        val sk3 = SecretKey.new()
 | 
			
		||||
        val sk1 = DecryptingSecretKey.new()
 | 
			
		||||
        val sk2 = DecryptingSecretKey(sk1.keyBytes)
 | 
			
		||||
        val sk3 = DecryptingSecretKey.new()
 | 
			
		||||
 | 
			
		||||
        assertEquals(sk1, sk2)
 | 
			
		||||
        assertEquals(sk2, sk1)
 | 
			
		||||
@ -408,13 +418,13 @@ class KeysTest {
 | 
			
		||||
    @Test
 | 
			
		||||
    fun testEncodedSizes2() = runTest {
 | 
			
		||||
        initCrypto()
 | 
			
		||||
        val x = SecretKey.new()
 | 
			
		||||
        val x = DecryptingSecretKey.new()
 | 
			
		||||
//        println("key bytes: ${x.keyBytes.size}:\n${x.keyBytes.toDump()}")
 | 
			
		||||
        val y = BipackEncoder.encode(x)
 | 
			
		||||
//        println("packed: ${y.size}: ${y.toDump()}")
 | 
			
		||||
        assertTrue { x.keyBytes.size + 5 > y.size }
 | 
			
		||||
        assertEquals(x, BipackDecoder.decode<SecretKey>(y))
 | 
			
		||||
        assertContentEquals(x.keyBytes, BipackDecoder.decode<SecretKey>(y).keyBytes)
 | 
			
		||||
        assertEquals(x, BipackDecoder.decode<DecryptingSecretKey>(y))
 | 
			
		||||
        assertContentEquals(x.keyBytes, BipackDecoder.decode<DecryptingSecretKey>(y).keyBytes)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
@ -422,7 +432,7 @@ class KeysTest {
 | 
			
		||||
        initCrypto()
 | 
			
		||||
        val k1 = SigningSecretKey.new()
 | 
			
		||||
        val k2 = k1.verifyingKey
 | 
			
		||||
        val k3 = SecretKey.new()
 | 
			
		||||
        val k3 = DecryptingSecretKey.new()
 | 
			
		||||
        val k4 = k3.publicKey
 | 
			
		||||
 | 
			
		||||
        val k5 = UniversalPrivateKey.new()
 | 
			
		||||
 | 
			
		||||
@ -1,3 +1,13 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2025. Sergey S. Chernov - All Rights Reserved
 | 
			
		||||
 *
 | 
			
		||||
 *  You may use, distribute and modify this code under the
 | 
			
		||||
 * terms of the private license, which you must obtain from the author
 | 
			
		||||
 *
 | 
			
		||||
 * To obtain the license, contact the author: https://t.me/real_sergeych or email to
 | 
			
		||||
 * real dot sergeych at gmail.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
import kotlinx.coroutines.test.runTest
 | 
			
		||||
import net.sergeych.crypto2.PBKD
 | 
			
		||||
import net.sergeych.crypto2.initCrypto
 | 
			
		||||
 | 
			
		||||
@ -1,3 +1,13 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2025. Sergey S. Chernov - All Rights Reserved
 | 
			
		||||
 *
 | 
			
		||||
 *  You may use, distribute and modify this code under the
 | 
			
		||||
 * terms of the private license, which you must obtain from the author
 | 
			
		||||
 *
 | 
			
		||||
 * To obtain the license, contact the author: https://t.me/real_sergeych or email to
 | 
			
		||||
 * real dot sergeych at gmail.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
import kotlinx.coroutines.test.runTest
 | 
			
		||||
import kotlinx.datetime.Instant
 | 
			
		||||
import net.sergeych.crypto2.initCrypto
 | 
			
		||||
 | 
			
		||||
@ -1,3 +1,13 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2025. Sergey S. Chernov - All Rights Reserved
 | 
			
		||||
 *
 | 
			
		||||
 *  You may use, distribute and modify this code under the
 | 
			
		||||
 * terms of the private license, which you must obtain from the author
 | 
			
		||||
 *
 | 
			
		||||
 * To obtain the license, contact the author: https://t.me/real_sergeych or email to
 | 
			
		||||
 * real dot sergeych at gmail.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
import com.ionspin.kotlin.crypto.util.encodeToUByteArray
 | 
			
		||||
import kotlinx.coroutines.test.runTest
 | 
			
		||||
import net.sergeych.bintools.toDump
 | 
			
		||||
@ -17,7 +27,7 @@ class RingTest {
 | 
			
		||||
        assertEquals(y1, y2)
 | 
			
		||||
 | 
			
		||||
        val e1 = Asymmetric.newSecretKey()
 | 
			
		||||
        val e2: SecretKey = BipackDecoder.decode(BipackEncoder.encode(e1))
 | 
			
		||||
        val e2: DecryptingSecretKey = BipackDecoder.decode(BipackEncoder.encode(e1))
 | 
			
		||||
        assertEquals(e1, e2)
 | 
			
		||||
 | 
			
		||||
        val k1 = SymmetricKey("1234567890Hello,dolly.here-we-go".encodeToUByteArray()) as UniversalKey
 | 
			
		||||
@ -154,14 +164,14 @@ class RingTest {
 | 
			
		||||
 | 
			
		||||
        var r1 = ra + rb + rc + rd
 | 
			
		||||
 | 
			
		||||
        assertEquals(a, r1.findKey<SecretKey>(a.id))
 | 
			
		||||
        assertEquals(a, r1.findKey<DecryptingSecretKey>(a.id))
 | 
			
		||||
        assertEquals(a, r1.keyByTag<UniversalKey>("foo_a"))
 | 
			
		||||
        assertEquals(b, r1.findKey<SigningKey>(b.id))
 | 
			
		||||
        assertEquals(c, r1.findById(c.id).first())
 | 
			
		||||
 | 
			
		||||
        r1 = UniversalRing.join(listOf(ra, rb, rc, rd))
 | 
			
		||||
 | 
			
		||||
        assertEquals(a, r1.findKey<SecretKey>(a.id))
 | 
			
		||||
        assertEquals(a, r1.findKey<DecryptingSecretKey>(a.id))
 | 
			
		||||
        assertEquals(a, r1.keyByTag<UniversalKey>("foo_a"))
 | 
			
		||||
        assertEquals(b, r1.findKey<SigningKey>(b.id))
 | 
			
		||||
        assertEquals(c, r1.findById(c.id).first())
 | 
			
		||||
 | 
			
		||||
@ -1,3 +1,13 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2025. Sergey S. Chernov - All Rights Reserved
 | 
			
		||||
 *
 | 
			
		||||
 *  You may use, distribute and modify this code under the
 | 
			
		||||
 * terms of the private license, which you must obtain from the author
 | 
			
		||||
 *
 | 
			
		||||
 * To obtain the license, contact the author: https://t.me/real_sergeych or email to
 | 
			
		||||
 * real dot sergeych at gmail.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
import kotlinx.coroutines.test.runTest
 | 
			
		||||
import net.sergeych.bintools.encodeToHex
 | 
			
		||||
import net.sergeych.crypto2.BinaryId
 | 
			
		||||
 | 
			
		||||
@ -1,3 +1,13 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2025. Sergey S. Chernov - All Rights Reserved
 | 
			
		||||
 *
 | 
			
		||||
 *  You may use, distribute and modify this code under the
 | 
			
		||||
 * terms of the private license, which you must obtain from the author
 | 
			
		||||
 *
 | 
			
		||||
 * To obtain the license, contact the author: https://t.me/real_sergeych or email to
 | 
			
		||||
 * real dot sergeych at gmail.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
import kotlin.test.fail
 | 
			
		||||
 | 
			
		||||
inline fun <reified T: Throwable>assertThrows(f: ()->Unit): T {
 | 
			
		||||
 | 
			
		||||
@ -1,3 +1,13 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2025. Sergey S. Chernov - All Rights Reserved
 | 
			
		||||
 *
 | 
			
		||||
 *  You may use, distribute and modify this code under the
 | 
			
		||||
 * terms of the private license, which you must obtain from the author
 | 
			
		||||
 *
 | 
			
		||||
 * To obtain the license, contact the author: https://t.me/real_sergeych or email to
 | 
			
		||||
 * real dot sergeych at gmail.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
import net.sergeych.bipack.BipackDecoder
 | 
			
		||||
import net.sergeych.bipack.BipackEncoder
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user