Asymmetric.Public now can be converted to Universal and stored into a ring
This commit is contained in:
		
							parent
							
								
									bb383b5457
								
							
						
					
					
						commit
						435604379e
					
				@ -109,7 +109,7 @@ object Asymmetric {
 | 
			
		||||
 | 
			
		||||
    private fun randomNonce(): UByteArray = randomUBytes(crypto_box_NONCEBYTES)
 | 
			
		||||
 | 
			
		||||
    fun new(): SecretKey = generateKeys().secretKey
 | 
			
		||||
    fun newSecretKey(): SecretKey = generateKeys().secretKey
 | 
			
		||||
 | 
			
		||||
    @Suppress("unused")
 | 
			
		||||
    val nonceBytesLength = crypto_box_NONCEBYTES
 | 
			
		||||
@ -121,7 +121,7 @@ object Asymmetric {
 | 
			
		||||
     * Anonymous encryption is very slow in comparison.
 | 
			
		||||
     */
 | 
			
		||||
    @Serializable
 | 
			
		||||
    class PublicKey(override val keyBytes: UByteArray) : BinaryKeyBase() {
 | 
			
		||||
    class PublicKey(override val keyBytes: UByteArray) : BinaryKeyBase(), KeyInstance {
 | 
			
		||||
 | 
			
		||||
        override val magick: KeysMagickNumber = KeysMagickNumber.defaultAssymmetric
 | 
			
		||||
 | 
			
		||||
@ -137,7 +137,7 @@ object Asymmetric {
 | 
			
		||||
         * proves that the message was not altered after creation.
 | 
			
		||||
         */
 | 
			
		||||
        fun encryptAnonymousMessage(plainData: UByteArray, randomFill: IntRange? = null): Message =
 | 
			
		||||
            encryptMessage(plainData,randomFill=randomFill)
 | 
			
		||||
            encryptMessage(plainData, randomFill = randomFill)
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Anonymous encryption, see [encryptAnonymousMessage], to binary data. Sender could not be identified.
 | 
			
		||||
@ -158,7 +158,7 @@ object Asymmetric {
 | 
			
		||||
        fun encryptMessage(
 | 
			
		||||
            plainData: UByteArray,
 | 
			
		||||
            nonce: UByteArray = randomNonce(),
 | 
			
		||||
            senderKey: SecretKey = new(),
 | 
			
		||||
            senderKey: SecretKey = newSecretKey(),
 | 
			
		||||
            randomFill: IntRange? = null,
 | 
			
		||||
        ) = createMessage(senderKey, this, WithFill.encode(plainData, randomFill), nonce)
 | 
			
		||||
 | 
			
		||||
@ -167,11 +167,14 @@ object Asymmetric {
 | 
			
		||||
         * [SecretKey] 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,
 | 
			
		||||
                           randomFill: IntRange? = null): Message =
 | 
			
		||||
        fun encryptMessage(
 | 
			
		||||
            plainData: UByteArray,
 | 
			
		||||
            senderKey: SecretKey,
 | 
			
		||||
            randomFill: IntRange? = null,
 | 
			
		||||
        ): Message =
 | 
			
		||||
            createMessage(senderKey, this, WithFill.encode(plainData, randomFill))
 | 
			
		||||
 | 
			
		||||
        fun toUniversalKey(): UniversalKey.Public = UniversalKey.Public(this)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
@ -209,8 +212,11 @@ object Asymmetric {
 | 
			
		||||
         * The corresponding public key
 | 
			
		||||
         */
 | 
			
		||||
        val publicKey: PublicKey by lazy {
 | 
			
		||||
            PublicKey(ScalarMultiplication.scalarMultiplicationBase(keyBytes))
 | 
			
		||||
                .also { cachedPublicKey = it }
 | 
			
		||||
            if (cachedPublicKey != null)
 | 
			
		||||
                cachedPublicKey!!
 | 
			
		||||
            else
 | 
			
		||||
                PublicKey(ScalarMultiplication.scalarMultiplicationBase(keyBytes))
 | 
			
		||||
                    .also { cachedPublicKey = it }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
@ -240,4 +246,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<SecretKey?, PublicKey>
 | 
			
		||||
 | 
			
		||||
@ -1,23 +1,7 @@
 | 
			
		||||
package net.sergeych.crypto2
 | 
			
		||||
 | 
			
		||||
import kotlinx.datetime.Instant
 | 
			
		||||
import kotlinx.serialization.Serializable
 | 
			
		||||
 | 
			
		||||
interface VerifyingKey {
 | 
			
		||||
    val id: KeyId
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Verify the signature and return true if it is correct.
 | 
			
		||||
     */
 | 
			
		||||
    fun verify(signature: UByteArray, message: UByteArray): Boolean
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
interface SigningKey {
 | 
			
		||||
    val verifyingKey: SigningPublicKey
 | 
			
		||||
    fun sign(message: UByteArray): UByteArray
 | 
			
		||||
    fun seal(message: UByteArray, expiresAt: Instant? = null): Seal
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@Serializable
 | 
			
		||||
abstract class BinaryKeyBase() {
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -235,7 +235,7 @@ sealed class Container {
 | 
			
		||||
                        recipient.id,
 | 
			
		||||
                        recipient.encryptMessage(
 | 
			
		||||
                            encodeMainKey,
 | 
			
		||||
                            senderKey = sender ?: Asymmetric.new(),
 | 
			
		||||
                            senderKey = sender ?: Asymmetric.newSecretKey(),
 | 
			
		||||
                        ).encoded
 | 
			
		||||
                    )
 | 
			
		||||
        }
 | 
			
		||||
@ -391,7 +391,7 @@ sealed class Container {
 | 
			
		||||
                Single(
 | 
			
		||||
                    pk.id, pk.encryptMessage(
 | 
			
		||||
                        plainData,
 | 
			
		||||
                        senderKey = sk ?: Asymmetric.new(),
 | 
			
		||||
                        senderKey = sk ?: Asymmetric.newSecretKey(),
 | 
			
		||||
                        randomFill = fillRange
 | 
			
		||||
                    ).encoded,
 | 
			
		||||
                    plainData,
 | 
			
		||||
 | 
			
		||||
@ -9,7 +9,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].
 | 
			
		||||
 */
 | 
			
		||||
interface DecryptingKey : NonceBased {
 | 
			
		||||
interface DecryptingKey : NonceBased, KeyInstance {
 | 
			
		||||
    /**
 | 
			
		||||
     * Authenticated decryption that checks the message is not tampered and therefor
 | 
			
		||||
     * the key is valid. It is not possible in general to distinguish whether the key is invalid
 | 
			
		||||
@ -28,8 +28,6 @@ interface DecryptingKey : NonceBased {
 | 
			
		||||
 | 
			
		||||
    fun decryptString(cipherData: UByteArray): String = decrypt(cipherData).decodeFromUByteArray()
 | 
			
		||||
 | 
			
		||||
    val id: KeyId
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline fun <reified T>DecryptingKey.decryptObject(cipherData: UByteArray): T =
 | 
			
		||||
 | 
			
		||||
@ -11,7 +11,7 @@ import net.sergeych.crypto2.SymmetricKey.WithNonce
 | 
			
		||||
 * It is not serializable by design.
 | 
			
		||||
 * Custom implementations are, see [SymmetricKey] for example.
 | 
			
		||||
 */
 | 
			
		||||
interface EncryptingKey : NonceBased {
 | 
			
		||||
interface EncryptingKey : NonceBased, KeyInstance {
 | 
			
		||||
    /**
 | 
			
		||||
     * Authenticated encrypting with optional random fill to protect from message size analysis.
 | 
			
		||||
     * Note that [randomFill] if present should be positive.
 | 
			
		||||
@ -27,8 +27,6 @@ interface EncryptingKey : NonceBased {
 | 
			
		||||
    fun encrypt(plainText: String,randomFill: IntRange? = null): UByteArray =
 | 
			
		||||
        encrypt(plainText.encodeToUByteArray(),randomFill)
 | 
			
		||||
 | 
			
		||||
    val id: KeyId
 | 
			
		||||
 | 
			
		||||
    fun encryptWithNonce(plainData: UByteArray, nonce: UByteArray, randomFill: IntRange? = null): UByteArray
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										14
									
								
								src/commonMain/kotlin/net/sergeych/crypto2/KeyInstance.kt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								src/commonMain/kotlin/net/sergeych/crypto2/KeyInstance.kt
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,14 @@
 | 
			
		||||
package net.sergeych.crypto2
 | 
			
		||||
 | 
			
		||||
interface KeyInstance {
 | 
			
		||||
    val id: KeyId
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Create a new instance of the corresponding key.
 | 
			
		||||
 */
 | 
			
		||||
@Suppress("unused")
 | 
			
		||||
fun KeyInstance.toUniversalKey(): UniversalKey {
 | 
			
		||||
    if (this is UniversalKey) return this
 | 
			
		||||
    return UniversalKey.from(this)
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										9
									
								
								src/commonMain/kotlin/net/sergeych/crypto2/SigningKey.kt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								src/commonMain/kotlin/net/sergeych/crypto2/SigningKey.kt
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,9 @@
 | 
			
		||||
package net.sergeych.crypto2
 | 
			
		||||
 | 
			
		||||
import kotlinx.datetime.Instant
 | 
			
		||||
 | 
			
		||||
interface SigningKey: KeyInstance {
 | 
			
		||||
    val verifyingKey: SigningPublicKey
 | 
			
		||||
    fun sign(message: UByteArray): UByteArray
 | 
			
		||||
    fun seal(message: UByteArray, expiresAt: Instant? = null): Seal
 | 
			
		||||
}
 | 
			
		||||
@ -4,8 +4,18 @@ import kotlinx.serialization.SerialName
 | 
			
		||||
import kotlinx.serialization.Serializable
 | 
			
		||||
import kotlinx.serialization.Transient
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Serializable implementation of the _any key_ conception. Allows serializing collections
 | 
			
		||||
 * of different keys with arbitrary types, such as [UniversalRing].
 | 
			
		||||
 *
 | 
			
		||||
 * To create an `UniversalKey` instance use [UniversalKey.from] or [KeyInstance]
 | 
			
		||||
 */
 | 
			
		||||
@Serializable
 | 
			
		||||
sealed class UniversalKey {
 | 
			
		||||
    /**
 | 
			
		||||
     * Propagate real ley instance. Base class itself can't be a key instance, but
 | 
			
		||||
     * has the same id. This allows requiring key instances in [UniversalRing].
 | 
			
		||||
     */
 | 
			
		||||
    abstract val id: KeyId
 | 
			
		||||
 | 
			
		||||
    @Serializable
 | 
			
		||||
@ -84,17 +94,18 @@ sealed class UniversalKey {
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    companion object {
 | 
			
		||||
        fun from(key: DecryptingKey): UniversalKey =
 | 
			
		||||
        fun from(key: KeyInstance): UniversalKey =
 | 
			
		||||
            when (key) {
 | 
			
		||||
                is UniversalKey -> key
 | 
			
		||||
                is Asymmetric.SecretKey -> Secret(key)
 | 
			
		||||
                is Asymmetric.PublicKey -> Public(key)
 | 
			
		||||
                is SymmetricKey -> Symmetric(key)
 | 
			
		||||
                is SafeKeyExchange.SessionKey -> Session(key)
 | 
			
		||||
                else -> throw UnsupportedOperationException("can't create universal key from ${key::class.simpleName}")
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        fun newSecretKey(): Secret =
 | 
			
		||||
            Secret(Asymmetric.new())
 | 
			
		||||
            Secret(Asymmetric.newSecretKey())
 | 
			
		||||
        fun newSigningKey(): Signing =
 | 
			
		||||
            Signing(SigningSecretKey.new())
 | 
			
		||||
        @Suppress("unused")
 | 
			
		||||
 | 
			
		||||
@ -2,6 +2,17 @@ package net.sergeych.crypto2
 | 
			
		||||
 | 
			
		||||
import kotlinx.serialization.Serializable
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Keyring capable of holding [UniversalKey] instances (serializable keys of different types)
 | 
			
		||||
 * associated with a set of string tags. Rings are used to decrypt [Container], to store
 | 
			
		||||
 * and find keys, etc.
 | 
			
		||||
 *
 | 
			
		||||
 * It is _immutable_ so it is safe to share id with no precautions on possible RC. Every
 | 
			
		||||
 * function that modifies the ring returns a _new instance_ of it.
 | 
			
		||||
 *
 | 
			
		||||
 * __important__ serialized keyring is not protected and can disclose keys. Encrypt it after
 | 
			
		||||
 * serializing before sending over the network or store on media.
 | 
			
		||||
 */
 | 
			
		||||
@Serializable
 | 
			
		||||
class UniversalRing(
 | 
			
		||||
    val keyWithTags: Map<UniversalKey, Set<String>>,
 | 
			
		||||
@ -11,19 +22,44 @@ class UniversalRing(
 | 
			
		||||
    constructor(vararg keyTags: Pair<UniversalKey, String>)
 | 
			
		||||
            : this(keyTags.associate { it.first to setOf(it.second) })
 | 
			
		||||
 | 
			
		||||
    val decryptingKeys: Set<DecryptingKey> by lazy { keys<DecryptingKey>() }
 | 
			
		||||
    /**
 | 
			
		||||
     * Only decrypting keys. This is a shortcut for [keysOfType]:
 | 
			
		||||
     * `keysOfType<DecryptingKey>()`.
 | 
			
		||||
     */
 | 
			
		||||
    val decryptingKeys: Set<DecryptingKey> by lazy { keysOfType<DecryptingKey>() }
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
     * Select keys of the specified type
 | 
			
		||||
     * Select all keys of the specified type. To select all keys, use [allKeys].
 | 
			
		||||
     */
 | 
			
		||||
    inline fun <reified T> keys(): Set<T> =
 | 
			
		||||
    inline fun <reified T: KeyInstance> keysOfType(): Set<T> =
 | 
			
		||||
        allKeys.mapNotNull { it as? T }.toSet()
 | 
			
		||||
 | 
			
		||||
    val allKeys: Set<UniversalKey> by lazy { keyWithTags.keys }
 | 
			
		||||
    
 | 
			
		||||
    inline fun <reified T> findKey(id: KeyId): UniversalKey? =
 | 
			
		||||
        allKeys.find { it is T && it.id == id }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Find a key of the specified type that matches the id. __Important__ it is not possible to
 | 
			
		||||
     * require [UniversalKey] as [T], it is not a [KeyInstance], while its descendants are, [UniversalKey.Secret], etc.
 | 
			
		||||
     * You can freely use [UniversalKey] subtypes or general key interfaces, e.g.
 | 
			
		||||
     * [EncryptingKey], [DecryptingKey], [SigningKey] and [VerifyingKey].
 | 
			
		||||
     *
 | 
			
		||||
     * Please avoid selecting parameters that make possible to pick more than one key, it will cause an exception.
 | 
			
		||||
     *
 | 
			
		||||
     * @return found key by id of the specified type or null
 | 
			
		||||
     * @throws IllegalArgumentException if there is more than one keys matching the criteria
 | 
			
		||||
     */
 | 
			
		||||
    inline fun <reified T: KeyInstance> findKey(id: KeyId): T? {
 | 
			
		||||
        val kk = allKeys.filter { it is T && it.id == id }
 | 
			
		||||
        if( kk.size > 1 )
 | 
			
		||||
            throw IllegalArgumentException(
 | 
			
		||||
                "ambiguous type selector ${T::class::simpleName}: ${kk.size} instances found, at most 1 allowed"
 | 
			
		||||
            )
 | 
			
		||||
        return kk.firstOrNull() as T?
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get all keys for the specified id (normally it could be 0, 1 or 2). See [KeyId] about
 | 
			
		||||
     * matching id keys.
 | 
			
		||||
     */
 | 
			
		||||
    fun keysById(id: KeyId): List<UniversalKey> = allKeys.filter { it.id == id }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
@ -40,8 +76,12 @@ class UniversalRing(
 | 
			
		||||
     */
 | 
			
		||||
    inline fun <reified T> keyByTag(tag: String) = keysByTags(tag).first { it is T }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get keys of the specified type having any of the specified tags associated.
 | 
			
		||||
     */
 | 
			
		||||
    @Suppress("unused")
 | 
			
		||||
    inline fun <reified T> keyByAnyTag(vararg tags: String) = keysByTags(*tags).first { it is T }
 | 
			
		||||
    inline fun <reified T> keysByAnyTag(vararg tags: String): Sequence<UniversalKey> =
 | 
			
		||||
        keysByTags(*tags).filter { it is T }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get all keys with a given id. Note that _matching keys_ have the same id, see [KeyId] for more.
 | 
			
		||||
@ -72,7 +112,7 @@ class UniversalRing(
 | 
			
		||||
     * both rings.
 | 
			
		||||
     */
 | 
			
		||||
    operator fun plus(other: UniversalRing): UniversalRing {
 | 
			
		||||
        var result = keyWithTags.toMutableMap()
 | 
			
		||||
        val result = keyWithTags.toMutableMap()
 | 
			
		||||
        for (e in other.keyWithTags.entries) {
 | 
			
		||||
            result[e.key]?.let {
 | 
			
		||||
                result[e.key] = it + e.value
 | 
			
		||||
@ -158,6 +198,7 @@ class UniversalRing(
 | 
			
		||||
    /**
 | 
			
		||||
     * Create string "report" of the ring contents. Note it has no trailing `\n`
 | 
			
		||||
     */
 | 
			
		||||
    @Suppress("unused")
 | 
			
		||||
    fun ls(): String {
 | 
			
		||||
        val result = mutableListOf<String>()
 | 
			
		||||
        for( e in keyWithTags.entries) {
 | 
			
		||||
@ -182,8 +223,19 @@ class UniversalRing(
 | 
			
		||||
            return keyRings.reduce { l, r -> l + r }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        fun from(vararg keys: DecryptingKey): UniversalRing =
 | 
			
		||||
        /**
 | 
			
		||||
         * Convert any keys to [UniversalKey] and form a ring with it.
 | 
			
		||||
         * @throws UnsupportedOperationException if [UniversalKey] can't build an instance of the specified class.
 | 
			
		||||
         */
 | 
			
		||||
        fun from(vararg keys: KeyInstance): UniversalRing =
 | 
			
		||||
            UniversalRing(keys.associate { UniversalKey.from(it) to setOf() } )
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Convert any keys to [UniversalKey] and form a ring with it.
 | 
			
		||||
         * @throws UnsupportedOperationException if [UniversalKey] can't build an instance of the specified class.
 | 
			
		||||
         */
 | 
			
		||||
        fun from(vararg keyTags: Pair<KeyInstance,String>): UniversalRing =
 | 
			
		||||
            UniversalRing(keyTags.associate { UniversalKey.from(it.first) to setOf(it.second) } )
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -0,0 +1,8 @@
 | 
			
		||||
package net.sergeych.crypto2
 | 
			
		||||
 | 
			
		||||
interface VerifyingKey: KeyInstance {
 | 
			
		||||
    /**
 | 
			
		||||
     * Verify the signature and return true if it is correct.
 | 
			
		||||
     */
 | 
			
		||||
    fun verify(signature: UByteArray, message: UByteArray): Boolean
 | 
			
		||||
}
 | 
			
		||||
@ -195,9 +195,9 @@ class KeysTest {
 | 
			
		||||
        assertEquals(usy2, usy1)
 | 
			
		||||
        assertFalse { usy1 == usy3 }
 | 
			
		||||
 | 
			
		||||
        val sk1 = Asymmetric.new()
 | 
			
		||||
        val sk1 = Asymmetric.newSecretKey()
 | 
			
		||||
        val sk2 = Asymmetric.SecretKey(sk1.keyBytes)
 | 
			
		||||
        val sk3 = Asymmetric.new()
 | 
			
		||||
        val sk3 = Asymmetric.newSecretKey()
 | 
			
		||||
 | 
			
		||||
        assertEquals(sk1, sk2)
 | 
			
		||||
        assertEquals(sk2, sk1)
 | 
			
		||||
 | 
			
		||||
@ -16,7 +16,7 @@ class RingTest {
 | 
			
		||||
        val y2 = SymmetricKey("1234567890Hello,dolly.here-we-go".encodeToUByteArray())
 | 
			
		||||
        assertEquals(y1, y2)
 | 
			
		||||
 | 
			
		||||
        val e1 = Asymmetric.new()
 | 
			
		||||
        val e1 = Asymmetric.newSecretKey()
 | 
			
		||||
        val e2: Asymmetric.SecretKey = BipackDecoder.decode(BipackEncoder.encode(e1))
 | 
			
		||||
        assertEquals(e1, e2)
 | 
			
		||||
 | 
			
		||||
@ -26,8 +26,8 @@ class RingTest {
 | 
			
		||||
        assertEquals(k1, k11)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        val k2 = UniversalKey.from(Asymmetric.new())
 | 
			
		||||
        val k3 = UniversalKey.from(Asymmetric.new())
 | 
			
		||||
        val k2 = UniversalKey.from(Asymmetric.newSecretKey())
 | 
			
		||||
        val k3 = UniversalKey.from(Asymmetric.newSecretKey())
 | 
			
		||||
//
 | 
			
		||||
        val r = UniversalRing(k1, k2)
 | 
			
		||||
//        val r = UniversalRing(k1)
 | 
			
		||||
@ -35,8 +35,8 @@ class RingTest {
 | 
			
		||||
        assertTrue(k1 in r)
 | 
			
		||||
        assertFalse { k3 in r }
 | 
			
		||||
 | 
			
		||||
        println(Asymmetric.new().keyBytes.size)
 | 
			
		||||
        println(BipackEncoder.encode(Asymmetric.new()).size)
 | 
			
		||||
        println(Asymmetric.newSecretKey().keyBytes.size)
 | 
			
		||||
        println(BipackEncoder.encode(Asymmetric.newSecretKey()).size)
 | 
			
		||||
        val encoded = BipackEncoder.encode(r)
 | 
			
		||||
        println(encoded.toDump())
 | 
			
		||||
        println(encoded.size)
 | 
			
		||||
@ -56,12 +56,28 @@ class RingTest {
 | 
			
		||||
        assertEquals(r, r2)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    fun testAsymmetricPublic() = runTest {
 | 
			
		||||
        initCrypto()
 | 
			
		||||
        val sk = Asymmetric.newSecretKey()
 | 
			
		||||
        assertEquals(sk.id, sk.publicKey.id)
 | 
			
		||||
        val r = UniversalRing.from(sk.publicKey to "foo")
 | 
			
		||||
        println(sk.publicKey.id)
 | 
			
		||||
        println(sk.id)
 | 
			
		||||
        println(r.findKey<EncryptingKey>(sk.id))
 | 
			
		||||
        println(BipackEncoder.encode(r).toDump())
 | 
			
		||||
        val r1 = deepCopy(r)
 | 
			
		||||
        println(r1.findKey<EncryptingKey>(sk.id))
 | 
			
		||||
        println(sk)
 | 
			
		||||
        assertTrue { sk.publicKey.toUniversalKey() == r1.findKey<EncryptingKey>(sk.id) }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    fun testTags() = runTest {
 | 
			
		||||
        initCrypto()
 | 
			
		||||
 | 
			
		||||
        val k1 = UniversalKey.from(SymmetricKey("1234567890Hello,dolly.here-we-go".encodeToUByteArray()))
 | 
			
		||||
        val k2 = UniversalKey.from(Asymmetric.new())
 | 
			
		||||
        val k2 = UniversalKey.from(Asymmetric.newSecretKey())
 | 
			
		||||
 | 
			
		||||
        val r1 = UniversalRing(k1, k2)
 | 
			
		||||
        var r2 = UniversalRing(deepCopy(k1), deepCopy(k2))
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user