From 06133ed6d66fdcf1186adbc30603580900cd6548 Mon Sep 17 00:00:00 2001 From: waltkb <68587968+waltkb@users.noreply.github.com> Date: Wed, 12 Feb 2025 21:25:09 +0100 Subject: [PATCH 01/12] Add secp256k1 & brainpool EC curves --- cryptography-core/src/commonMain/kotlin/algorithms/EC.kt | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/cryptography-core/src/commonMain/kotlin/algorithms/EC.kt b/cryptography-core/src/commonMain/kotlin/algorithms/EC.kt index aa914f25..c669316b 100644 --- a/cryptography-core/src/commonMain/kotlin/algorithms/EC.kt +++ b/cryptography-core/src/commonMain/kotlin/algorithms/EC.kt @@ -20,6 +20,13 @@ public interface EC Date: Wed, 12 Feb 2025 21:25:19 +0100 Subject: [PATCH 02/12] Add Ed (edwards curve), EdDSA (Ed25519/Ed448) and XDH (X25519/X448) interfaces --- .../src/commonMain/kotlin/algorithms/Ed.kt | 76 +++++++++++++++++++ .../src/commonMain/kotlin/algorithms/EdDSA.kt | 26 +++++++ .../src/commonMain/kotlin/algorithms/XDH.kt | 25 ++++++ 3 files changed, 127 insertions(+) create mode 100644 cryptography-core/src/commonMain/kotlin/algorithms/Ed.kt create mode 100644 cryptography-core/src/commonMain/kotlin/algorithms/EdDSA.kt create mode 100644 cryptography-core/src/commonMain/kotlin/algorithms/XDH.kt diff --git a/cryptography-core/src/commonMain/kotlin/algorithms/Ed.kt b/cryptography-core/src/commonMain/kotlin/algorithms/Ed.kt new file mode 100644 index 00000000..3f3bf50f --- /dev/null +++ b/cryptography-core/src/commonMain/kotlin/algorithms/Ed.kt @@ -0,0 +1,76 @@ +package algorithms + +import dev.whyoleg.cryptography.* +import dev.whyoleg.cryptography.materials.key.* +import kotlin.jvm.* + +@SubclassOptInRequired(CryptographyProviderApi::class) +public interface Ed> : CryptographyAlgorithm { + public fun publicKeyDecoder(curve: Curve): KeyDecoder + public fun privateKeyDecoder(curve: Curve): KeyDecoder + public fun keyPairGenerator(curve: Curve): KeyGenerator + + @JvmInline + public value class Curve(public val name: String) { + public companion object { + public val Ed25519: Curve get() = Curve("Ed25519") + public val X25519: Curve get() = Curve("X25519") + + public val Ed448: Curve get() = Curve("Ed448") + public val X448: Curve get() = Curve("X448") + } + } + + // Similar key interfaces but with Edwards-specific formats + @SubclassOptInRequired(CryptographyProviderApi::class) + public interface KeyPair : Key { + public val publicKey: PublicK + public val privateKey: PrivateK + } + + @SubclassOptInRequired(CryptographyProviderApi::class) + public interface PublicKey : EncodableKey { + public sealed class Format : KeyFormat { + final override fun toString(): String = name + + public data object JWK : Format() { + override val name: String get() = "JWK" + } + + public data object RAW : Format() { + override val name: String get() = "RAW" + } + + public data object DER : Format() { + override val name: String get() = "DER" + } + + public data object PEM : Format() { + override val name: String get() = "PEM" + } + } + } + + @SubclassOptInRequired(CryptographyProviderApi::class) + public interface PrivateKey : EncodableKey { + public sealed class Format : KeyFormat { + final override fun toString(): String = name + + public data object JWK : Format() { + override val name: String get() = "JWK" + } + + public data object RAW : Format() { + override val name: String get() = "RAW" + } + + public data object DER : Format() { + override val name: String get() = "DER" + } + + public data object PEM : Format() { + override val name: String get() = "PEM" + } + } + } +} diff --git a/cryptography-core/src/commonMain/kotlin/algorithms/EdDSA.kt b/cryptography-core/src/commonMain/kotlin/algorithms/EdDSA.kt new file mode 100644 index 00000000..489be029 --- /dev/null +++ b/cryptography-core/src/commonMain/kotlin/algorithms/EdDSA.kt @@ -0,0 +1,26 @@ +package algorithms + +import dev.whyoleg.cryptography.CryptographyAlgorithmId +import dev.whyoleg.cryptography.CryptographyProviderApi +import dev.whyoleg.cryptography.operations.SignatureGenerator +import dev.whyoleg.cryptography.operations.SignatureVerifier + +@SubclassOptInRequired(CryptographyProviderApi::class) +public interface EdDSA : Ed { + override val id: CryptographyAlgorithmId get() = Companion + + public companion object : CryptographyAlgorithmId("EdDSA") + + @SubclassOptInRequired(CryptographyProviderApi::class) + public interface KeyPair : Ed.KeyPair + + @SubclassOptInRequired(CryptographyProviderApi::class) + public interface PublicKey : Ed.PublicKey { + public fun signatureVerifier(): SignatureVerifier + } + + @SubclassOptInRequired(CryptographyProviderApi::class) + public interface PrivateKey : Ed.PrivateKey { + public fun signatureGenerator(): SignatureGenerator + } +} diff --git a/cryptography-core/src/commonMain/kotlin/algorithms/XDH.kt b/cryptography-core/src/commonMain/kotlin/algorithms/XDH.kt new file mode 100644 index 00000000..91a0ca77 --- /dev/null +++ b/cryptography-core/src/commonMain/kotlin/algorithms/XDH.kt @@ -0,0 +1,25 @@ +package algorithms + +import dev.whyoleg.cryptography.CryptographyAlgorithmId +import dev.whyoleg.cryptography.CryptographyProviderApi +import dev.whyoleg.cryptography.operations.SharedSecretGenerator + +@SubclassOptInRequired(CryptographyProviderApi::class) +public interface XDH : Ed { + override val id: CryptographyAlgorithmId get() = Companion + + public companion object : CryptographyAlgorithmId("XDH") + + @SubclassOptInRequired(CryptographyProviderApi::class) + public interface KeyPair : Ed.KeyPair + + @SubclassOptInRequired(CryptographyProviderApi::class) + public interface PublicKey : Ed.PublicKey { + public fun sharedSecretGenerator(): SharedSecretGenerator + } + + @SubclassOptInRequired(CryptographyProviderApi::class) + public interface PrivateKey : Ed.PrivateKey { + public fun sharedSecretGenerator(): SharedSecretGenerator + } +} From 1be8ed634d343d6d173ec05e9982f241e8aba987 Mon Sep 17 00:00:00 2001 From: waltkb <68587968+waltkb@users.noreply.github.com> Date: Wed, 12 Feb 2025 21:25:26 +0100 Subject: [PATCH 03/12] Add JDK implementation for Ed (edwards curve), EdDSA (Ed25519/Ed448) and XDH (X25519/X448) interfaces --- .../src/jvmMain/kotlin/algorithms/JdkEd.kt | 107 ++++++++++++++++++ .../src/jvmMain/kotlin/algorithms/JdkEdDSA.kt | 39 +++++++ .../src/jvmMain/kotlin/algorithms/JdkXDH.kt | 43 +++++++ 3 files changed, 189 insertions(+) create mode 100644 cryptography-providers/jdk/src/jvmMain/kotlin/algorithms/JdkEd.kt create mode 100644 cryptography-providers/jdk/src/jvmMain/kotlin/algorithms/JdkEdDSA.kt create mode 100644 cryptography-providers/jdk/src/jvmMain/kotlin/algorithms/JdkXDH.kt diff --git a/cryptography-providers/jdk/src/jvmMain/kotlin/algorithms/JdkEd.kt b/cryptography-providers/jdk/src/jvmMain/kotlin/algorithms/JdkEd.kt new file mode 100644 index 00000000..a9825768 --- /dev/null +++ b/cryptography-providers/jdk/src/jvmMain/kotlin/algorithms/JdkEd.kt @@ -0,0 +1,107 @@ +package algorithms + +import dev.whyoleg.cryptography.materials.key.KeyDecoder +import dev.whyoleg.cryptography.materials.key.KeyGenerator +import dev.whyoleg.cryptography.providers.jdk.JKeyPair +import dev.whyoleg.cryptography.providers.jdk.JKeyPairGenerator +import dev.whyoleg.cryptography.providers.jdk.JPrivateKey +import dev.whyoleg.cryptography.providers.jdk.JPublicKey +import dev.whyoleg.cryptography.providers.jdk.JdkCryptographyState +import dev.whyoleg.cryptography.providers.jdk.materials.JdkEncodableKey +import dev.whyoleg.cryptography.providers.jdk.materials.JdkKeyPairGenerator +import dev.whyoleg.cryptography.providers.jdk.materials.JdkPrivateKeyDecoder +import dev.whyoleg.cryptography.providers.jdk.materials.JdkPublicKeyDecoder +import dev.whyoleg.cryptography.providers.jdk.materials.unwrapPem +import dev.whyoleg.cryptography.providers.jdk.materials.wrapPem +import dev.whyoleg.cryptography.serialization.pem.PemLabel +//import java.security.spec.XECPublicKeySpec // TODO: for raw encoding + +internal sealed class JdkEd>( + protected val state: JdkCryptographyState, +) : Ed { + protected abstract fun JPublicKey.convert(): PublicK + protected abstract fun JPrivateKey.convert(): PrivateK + protected abstract fun JKeyPair.convert(): KP + + final override fun publicKeyDecoder(curve: Ed.Curve): KeyDecoder { + return EdPublicKeyDecoder(curve.jdkName) + } + + final override fun privateKeyDecoder(curve: Ed.Curve): KeyDecoder { + return EdPrivateKeyDecoder(curve.jdkName) + } + + final override fun keyPairGenerator(curve: Ed.Curve): KeyGenerator { + return EdKeyPairGenerator(curve.jdkName) + } + + private val Ed.Curve.jdkName: String get() = name + + private inner class EdKeyPairGenerator( + private val algorithm: String, + ) : JdkKeyPairGenerator(state, algorithm) { + override fun JKeyPairGenerator.init() { + //initialize(null, state.secureRandom) // TODO + } + + override fun JKeyPair.convert(): KP = with(this@JdkEd) { convert() } + } + + private inner class EdPublicKeyDecoder( + private val algorithm: String, + ) : JdkPublicKeyDecoder(state, algorithm) { + override fun JPublicKey.convert(): PublicK = with(this@JdkEd) { convert() } + + override fun decodeFromByteArrayBlocking(format: Ed.PublicKey.Format, bytes: ByteArray): PublicK = when (format) { + Ed.PublicKey.Format.JWK -> error("$format is not supported") + /* Ed.PublicKey.Format.RAW -> keyFactory.use { + it.generatePublic(XECPublicKeySpec(NamedParameterSpec(algorithm), bytes)) + }.convert()*/ // TODO: for raw encoding + Ed.PublicKey.Format.RAW -> TODO("Todo: raw encoding") + Ed.PublicKey.Format.DER -> decodeFromDer(bytes) + Ed.PublicKey.Format.PEM -> decodeFromDer(unwrapPem(PemLabel.PublicKey, bytes)) + } + } + + private inner class EdPrivateKeyDecoder( + private val algorithm: String, + ) : JdkPrivateKeyDecoder(state, algorithm) { + override fun JPrivateKey.convert(): PrivateK = with(this@JdkEd) { convert() } + + override fun decodeFromByteArrayBlocking(format: Ed.PrivateKey.Format, bytes: ByteArray): PrivateK = when (format) { + Ed.PrivateKey.Format.JWK -> error("$format is not supported") + Ed.PrivateKey.Format.RAW -> TODO("Todo: raw encoding") + /*Ed.PrivateKey.Format.RAW -> keyFactory.use { + it.generatePrivate(XECPrivateKeySpec(NamedParameterSpec(algorithm), bytes)) + }.convert()*/ // TODO: for raw encoding + Ed.PrivateKey.Format.DER -> decodeFromDer(bytes) + Ed.PrivateKey.Format.PEM -> decodeFromDer(unwrapPem(PemLabel.PrivateKey, bytes)) + } + } + + protected abstract class BaseEdPublicKey( + private val key: JPublicKey, + ) : Ed.PublicKey, JdkEncodableKey(key) { + final override fun encodeToByteArrayBlocking(format: Ed.PublicKey.Format): ByteArray = when (format) { + Ed.PublicKey.Format.JWK -> error("$format is not supported") + Ed.PublicKey.Format.RAW -> TODO("Todo: raw encoding") +// Ed.PublicKey.Format.RAW -> (key as XECPublicKey).encoded + Ed.PublicKey.Format.DER -> encodeToDer() + Ed.PublicKey.Format.PEM -> wrapPem(PemLabel.PublicKey, encodeToDer()) + else -> TODO() + } + } + + protected abstract class BaseEdPrivateKey( + private val key: JPrivateKey, + ) : Ed.PrivateKey, JdkEncodableKey(key) { + final override fun encodeToByteArrayBlocking(format: Ed.PrivateKey.Format): ByteArray = when (format) { + Ed.PrivateKey.Format.JWK -> error("$format is not supported") + Ed.PrivateKey.Format.RAW -> TODO("Todo: raw encoding") +// Ed.PrivateKey.Format.RAW -> (key as XECPrivateKey).encoded + Ed.PrivateKey.Format.DER -> encodeToDer() + Ed.PrivateKey.Format.PEM -> wrapPem(PemLabel.PrivateKey, encodeToDer()) + else -> TODO() + } + } +} diff --git a/cryptography-providers/jdk/src/jvmMain/kotlin/algorithms/JdkEdDSA.kt b/cryptography-providers/jdk/src/jvmMain/kotlin/algorithms/JdkEdDSA.kt new file mode 100644 index 00000000..9e0b9455 --- /dev/null +++ b/cryptography-providers/jdk/src/jvmMain/kotlin/algorithms/JdkEdDSA.kt @@ -0,0 +1,39 @@ +package algorithms + +import dev.whyoleg.cryptography.operations.SignatureGenerator +import dev.whyoleg.cryptography.operations.SignatureVerifier +import dev.whyoleg.cryptography.providers.jdk.JKeyPair +import dev.whyoleg.cryptography.providers.jdk.JPrivateKey +import dev.whyoleg.cryptography.providers.jdk.JPublicKey +import dev.whyoleg.cryptography.providers.jdk.JdkCryptographyState +import dev.whyoleg.cryptography.providers.jdk.operations.JdkSignatureGenerator +import dev.whyoleg.cryptography.providers.jdk.operations.JdkSignatureVerifier + +internal class JdkEdDSA(state: JdkCryptographyState) : JdkEd(state), EdDSA { + override fun JPublicKey.convert(): EdDSA.PublicKey = EdDsaPublicKey(state, this) + override fun JPrivateKey.convert(): EdDSA.PrivateKey = EdDsaPrivateKey(state, this) + override fun JKeyPair.convert(): EdDSA.KeyPair = EdDsaKeyPair(public.convert(), private.convert()) + + private class EdDsaKeyPair( + override val publicKey: EdDSA.PublicKey, + override val privateKey: EdDSA.PrivateKey, + ) : EdDSA.KeyPair + + private class EdDsaPublicKey( + private val state: JdkCryptographyState, + private val key: JPublicKey, + ) : EdDSA.PublicKey, BaseEdPublicKey(key) { + override fun signatureVerifier(): SignatureVerifier { + return JdkSignatureVerifier(state, key, "EdDSA", null) + } + } + + private class EdDsaPrivateKey( + private val state: JdkCryptographyState, + private val key: JPrivateKey, + ) : EdDSA.PrivateKey, BaseEdPrivateKey(key) { + override fun signatureGenerator(): SignatureGenerator { + return JdkSignatureGenerator(state, key, "EdDSA", null) + } + } +} diff --git a/cryptography-providers/jdk/src/jvmMain/kotlin/algorithms/JdkXDH.kt b/cryptography-providers/jdk/src/jvmMain/kotlin/algorithms/JdkXDH.kt new file mode 100644 index 00000000..799e2924 --- /dev/null +++ b/cryptography-providers/jdk/src/jvmMain/kotlin/algorithms/JdkXDH.kt @@ -0,0 +1,43 @@ +package algorithms + +import dev.whyoleg.cryptography.operations.SharedSecretGenerator +import dev.whyoleg.cryptography.providers.jdk.JKeyPair +import dev.whyoleg.cryptography.providers.jdk.JPrivateKey +import dev.whyoleg.cryptography.providers.jdk.JPublicKey +import dev.whyoleg.cryptography.providers.jdk.JdkCryptographyState +import dev.whyoleg.cryptography.providers.jdk.operations.doAgreement + +internal class JdkXDH(state: JdkCryptographyState) : JdkEd(state), XDH { + override fun JPublicKey.convert(): XDH.PublicKey = XdhPublicKey(state, this) + override fun JPrivateKey.convert(): XDH.PrivateKey = XdhPrivateKey(state, this) + override fun JKeyPair.convert(): XDH.KeyPair = XdhKeyPair(public.convert(), private.convert()) + + private class XdhKeyPair( + override val publicKey: XDH.PublicKey, + override val privateKey: XDH.PrivateKey, + ) : XDH.KeyPair + + private class XdhPublicKey( + private val state: JdkCryptographyState, + val key: JPublicKey, + ) : XDH.PublicKey, BaseEdPublicKey(key), SharedSecretGenerator { + private val keyAgreement = state.keyAgreement("XDH") + override fun sharedSecretGenerator(): SharedSecretGenerator = this + override fun generateSharedSecretToByteArrayBlocking(other: XDH.PrivateKey): ByteArray { + check(other is XdhPrivateKey) { "Only key produced by JDK provider is supported" } + return keyAgreement.doAgreement(state, other.key, key) + } + } + + private class XdhPrivateKey( + private val state: JdkCryptographyState, + val key: JPrivateKey, + ) : XDH.PrivateKey, BaseEdPrivateKey(key), SharedSecretGenerator { + private val keyAgreement = state.keyAgreement("XDH") + override fun sharedSecretGenerator(): SharedSecretGenerator = this + override fun generateSharedSecretToByteArrayBlocking(other: XDH.PublicKey): ByteArray { + check(other is XdhPublicKey) { "Only key produced by JDK provider is supported" } + return keyAgreement.doAgreement(state, key, other.key) + } + } +} From cb09961ae0301feacdcd44aa9cca1ab25d56742f Mon Sep 17 00:00:00 2001 From: waltkb <68587968+waltkb@users.noreply.github.com> Date: Wed, 12 Feb 2025 21:25:30 +0100 Subject: [PATCH 04/12] Add new interfaces to JdkCryptographyProvider and format list --- .../jvmMain/kotlin/JdkCryptographyProvider.kt | 23 +++++++++++-------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/cryptography-providers/jdk/src/jvmMain/kotlin/JdkCryptographyProvider.kt b/cryptography-providers/jdk/src/jvmMain/kotlin/JdkCryptographyProvider.kt index 470150d1..08bc3725 100644 --- a/cryptography-providers/jdk/src/jvmMain/kotlin/JdkCryptographyProvider.kt +++ b/cryptography-providers/jdk/src/jvmMain/kotlin/JdkCryptographyProvider.kt @@ -4,6 +4,7 @@ package dev.whyoleg.cryptography.providers.jdk +import algorithms.* import dev.whyoleg.cryptography.* import dev.whyoleg.cryptography.algorithms.* import dev.whyoleg.cryptography.providers.jdk.algorithms.* @@ -78,19 +79,21 @@ internal class JdkCryptographyProvider( SHA3_384 -> JdkDigest(state, "SHA3-384", SHA3_384) SHA3_512 -> JdkDigest(state, "SHA3-512", SHA3_512) RIPEMD160 -> JdkDigest(state, "RIPEMD160", RIPEMD160) - HMAC -> JdkHmac(state) - AES.CBC -> JdkAesCbc(state) - AES.CTR -> JdkAesCtr(state) - AES.ECB -> JdkAesEcb(state) - AES.GCM -> JdkAesGcm(state) - RSA.OAEP -> JdkRsaOaep(state) + HMAC -> JdkHmac(state) + AES.CBC -> JdkAesCbc(state) + AES.CTR -> JdkAesCtr(state) + AES.ECB -> JdkAesEcb(state) + AES.GCM -> JdkAesGcm(state) + RSA.OAEP -> JdkRsaOaep(state) RSA.PSS -> JdkRsaPss(state) RSA.PKCS1 -> JdkRsaPkcs1(state) - RSA.RAW -> JdkRsaRaw(state) + RSA.RAW -> JdkRsaRaw(state) ECDSA -> JdkEcdsa(state) - ECDH -> JdkEcdh(state) - PBKDF2 -> JdkPbkdf2(state) - HKDF -> JdkHkdf(state, this) + EdDSA -> JdkEdDSA(state) + ECDH -> JdkEcdh(state) + XDH -> JdkXDH(state) + PBKDF2 -> JdkPbkdf2(state) + HKDF -> JdkHkdf(state, this) else -> null } } as A? From 1665f5bd4df2542639392aa69a6ed6235a1f52ed Mon Sep 17 00:00:00 2001 From: waltkb <68587968+waltkb@users.noreply.github.com> Date: Thu, 13 Feb 2025 12:09:57 +0100 Subject: [PATCH 05/12] Updated .api definitions --- cryptography-core/api/cryptography-core.api | 145 +++++++++++++++++ .../api/cryptography-core.klib.api | 153 ++++++++++++++++++ 2 files changed, 298 insertions(+) diff --git a/cryptography-core/api/cryptography-core.api b/cryptography-core/api/cryptography-core.api index 327b419d..1d127fac 100644 --- a/cryptography-core/api/cryptography-core.api +++ b/cryptography-core/api/cryptography-core.api @@ -1,3 +1,144 @@ +public abstract interface class algorithms/Ed : dev/whyoleg/cryptography/CryptographyAlgorithm { + public abstract fun keyPairGenerator-48_mLeQ (Ljava/lang/String;)Ldev/whyoleg/cryptography/materials/key/KeyGenerator; + public abstract fun privateKeyDecoder-48_mLeQ (Ljava/lang/String;)Ldev/whyoleg/cryptography/materials/key/KeyDecoder; + public abstract fun publicKeyDecoder-48_mLeQ (Ljava/lang/String;)Ldev/whyoleg/cryptography/materials/key/KeyDecoder; +} + +public final class algorithms/Ed$Curve { + public static final field Companion Lalgorithms/Ed$Curve$Companion; + public static final synthetic fun box-impl (Ljava/lang/String;)Lalgorithms/Ed$Curve; + public static fun constructor-impl (Ljava/lang/String;)Ljava/lang/String; + public fun equals (Ljava/lang/Object;)Z + public static fun equals-impl (Ljava/lang/String;Ljava/lang/Object;)Z + public static final fun equals-impl0 (Ljava/lang/String;Ljava/lang/String;)Z + public final fun getName ()Ljava/lang/String; + public fun hashCode ()I + public static fun hashCode-impl (Ljava/lang/String;)I + public fun toString ()Ljava/lang/String; + public static fun toString-impl (Ljava/lang/String;)Ljava/lang/String; + public final synthetic fun unbox-impl ()Ljava/lang/String; +} + +public final class algorithms/Ed$Curve$Companion { + public final fun getEd25519-ZWrx85M ()Ljava/lang/String; + public final fun getEd448-ZWrx85M ()Ljava/lang/String; + public final fun getX25519-ZWrx85M ()Ljava/lang/String; + public final fun getX448-ZWrx85M ()Ljava/lang/String; +} + +public abstract interface class algorithms/Ed$KeyPair : dev/whyoleg/cryptography/materials/key/Key { + public abstract fun getPrivateKey ()Lalgorithms/Ed$PrivateKey; + public abstract fun getPublicKey ()Lalgorithms/Ed$PublicKey; +} + +public abstract interface class algorithms/Ed$PrivateKey : dev/whyoleg/cryptography/materials/key/EncodableKey { +} + +public abstract class algorithms/Ed$PrivateKey$Format : dev/whyoleg/cryptography/materials/key/KeyFormat { + public final fun toString ()Ljava/lang/String; +} + +public final class algorithms/Ed$PrivateKey$Format$DER : algorithms/Ed$PrivateKey$Format { + public static final field INSTANCE Lalgorithms/Ed$PrivateKey$Format$DER; + public fun equals (Ljava/lang/Object;)Z + public fun getName ()Ljava/lang/String; + public fun hashCode ()I +} + +public final class algorithms/Ed$PrivateKey$Format$JWK : algorithms/Ed$PrivateKey$Format { + public static final field INSTANCE Lalgorithms/Ed$PrivateKey$Format$JWK; + public fun equals (Ljava/lang/Object;)Z + public fun getName ()Ljava/lang/String; + public fun hashCode ()I +} + +public final class algorithms/Ed$PrivateKey$Format$PEM : algorithms/Ed$PrivateKey$Format { + public static final field INSTANCE Lalgorithms/Ed$PrivateKey$Format$PEM; + public fun equals (Ljava/lang/Object;)Z + public fun getName ()Ljava/lang/String; + public fun hashCode ()I +} + +public final class algorithms/Ed$PrivateKey$Format$RAW : algorithms/Ed$PrivateKey$Format { + public static final field INSTANCE Lalgorithms/Ed$PrivateKey$Format$RAW; + public fun equals (Ljava/lang/Object;)Z + public fun getName ()Ljava/lang/String; + public fun hashCode ()I +} + +public abstract interface class algorithms/Ed$PublicKey : dev/whyoleg/cryptography/materials/key/EncodableKey { +} + +public abstract class algorithms/Ed$PublicKey$Format : dev/whyoleg/cryptography/materials/key/KeyFormat { + public final fun toString ()Ljava/lang/String; +} + +public final class algorithms/Ed$PublicKey$Format$DER : algorithms/Ed$PublicKey$Format { + public static final field INSTANCE Lalgorithms/Ed$PublicKey$Format$DER; + public fun equals (Ljava/lang/Object;)Z + public fun getName ()Ljava/lang/String; + public fun hashCode ()I +} + +public final class algorithms/Ed$PublicKey$Format$JWK : algorithms/Ed$PublicKey$Format { + public static final field INSTANCE Lalgorithms/Ed$PublicKey$Format$JWK; + public fun equals (Ljava/lang/Object;)Z + public fun getName ()Ljava/lang/String; + public fun hashCode ()I +} + +public final class algorithms/Ed$PublicKey$Format$PEM : algorithms/Ed$PublicKey$Format { + public static final field INSTANCE Lalgorithms/Ed$PublicKey$Format$PEM; + public fun equals (Ljava/lang/Object;)Z + public fun getName ()Ljava/lang/String; + public fun hashCode ()I +} + +public final class algorithms/Ed$PublicKey$Format$RAW : algorithms/Ed$PublicKey$Format { + public static final field INSTANCE Lalgorithms/Ed$PublicKey$Format$RAW; + public fun equals (Ljava/lang/Object;)Z + public fun getName ()Ljava/lang/String; + public fun hashCode ()I +} + +public abstract interface class algorithms/EdDSA : algorithms/Ed { + public static final field Companion Lalgorithms/EdDSA$Companion; + public fun getId ()Ldev/whyoleg/cryptography/CryptographyAlgorithmId; +} + +public final class algorithms/EdDSA$Companion : dev/whyoleg/cryptography/CryptographyAlgorithmId { +} + +public abstract interface class algorithms/EdDSA$KeyPair : algorithms/Ed$KeyPair { +} + +public abstract interface class algorithms/EdDSA$PrivateKey : algorithms/Ed$PrivateKey { + public abstract fun signatureGenerator ()Ldev/whyoleg/cryptography/operations/SignatureGenerator; +} + +public abstract interface class algorithms/EdDSA$PublicKey : algorithms/Ed$PublicKey { + public abstract fun signatureVerifier ()Ldev/whyoleg/cryptography/operations/SignatureVerifier; +} + +public abstract interface class algorithms/XDH : algorithms/Ed { + public static final field Companion Lalgorithms/XDH$Companion; + public fun getId ()Ldev/whyoleg/cryptography/CryptographyAlgorithmId; +} + +public final class algorithms/XDH$Companion : dev/whyoleg/cryptography/CryptographyAlgorithmId { +} + +public abstract interface class algorithms/XDH$KeyPair : algorithms/Ed$KeyPair { +} + +public abstract interface class algorithms/XDH$PrivateKey : algorithms/Ed$PrivateKey { + public abstract fun sharedSecretGenerator ()Ldev/whyoleg/cryptography/operations/SharedSecretGenerator; +} + +public abstract interface class algorithms/XDH$PublicKey : algorithms/Ed$PublicKey { + public abstract fun sharedSecretGenerator ()Ldev/whyoleg/cryptography/operations/SharedSecretGenerator; +} + public final class dev/whyoleg/cryptography/BinarySize : java/lang/Comparable { public static final field Companion Ldev/whyoleg/cryptography/BinarySize$Companion; public static final synthetic fun box-impl (I)Ldev/whyoleg/cryptography/BinarySize; @@ -253,9 +394,13 @@ public final class dev/whyoleg/cryptography/algorithms/EC$Curve { } public final class dev/whyoleg/cryptography/algorithms/EC$Curve$Companion { + public final fun getBrainpoolP256r1-pVITJAk ()Ljava/lang/String; + public final fun getBrainpoolP384r1-pVITJAk ()Ljava/lang/String; + public final fun getBrainpoolP512r1-pVITJAk ()Ljava/lang/String; public final fun getP256-pVITJAk ()Ljava/lang/String; public final fun getP384-pVITJAk ()Ljava/lang/String; public final fun getP521-pVITJAk ()Ljava/lang/String; + public final fun getSecp256k1-pVITJAk ()Ljava/lang/String; } public abstract interface class dev/whyoleg/cryptography/algorithms/EC$KeyPair : dev/whyoleg/cryptography/materials/key/Key { diff --git a/cryptography-core/api/cryptography-core.klib.api b/cryptography-core/api/cryptography-core.klib.api index 4d43f5b9..91f77c63 100644 --- a/cryptography-core/api/cryptography-core.klib.api +++ b/cryptography-core/api/cryptography-core.klib.api @@ -14,6 +14,117 @@ open annotation class dev.whyoleg.cryptography/DelicateCryptographyApi : kotlin/ constructor () // dev.whyoleg.cryptography/DelicateCryptographyApi.|(){}[0] } +abstract interface <#A: algorithms/Ed.PublicKey, #B: algorithms/Ed.PrivateKey, #C: algorithms/Ed.KeyPair<#A, #B>> algorithms/Ed : dev.whyoleg.cryptography/CryptographyAlgorithm { // algorithms/Ed|null[0] + abstract fun keyPairGenerator(algorithms/Ed.Curve): dev.whyoleg.cryptography.materials.key/KeyGenerator<#C> // algorithms/Ed.keyPairGenerator|keyPairGenerator(algorithms.Ed.Curve){}[0] + abstract fun privateKeyDecoder(algorithms/Ed.Curve): dev.whyoleg.cryptography.materials.key/KeyDecoder // algorithms/Ed.privateKeyDecoder|privateKeyDecoder(algorithms.Ed.Curve){}[0] + abstract fun publicKeyDecoder(algorithms/Ed.Curve): dev.whyoleg.cryptography.materials.key/KeyDecoder // algorithms/Ed.publicKeyDecoder|publicKeyDecoder(algorithms.Ed.Curve){}[0] + + abstract interface <#A1: algorithms/Ed.PublicKey, #B1: algorithms/Ed.PrivateKey> KeyPair : dev.whyoleg.cryptography.materials.key/Key { // algorithms/Ed.KeyPair|null[0] + abstract val privateKey // algorithms/Ed.KeyPair.privateKey|{}privateKey[0] + abstract fun (): #B1 // algorithms/Ed.KeyPair.privateKey.|(){}[0] + abstract val publicKey // algorithms/Ed.KeyPair.publicKey|{}publicKey[0] + abstract fun (): #A1 // algorithms/Ed.KeyPair.publicKey.|(){}[0] + } + + abstract interface PrivateKey : dev.whyoleg.cryptography.materials.key/EncodableKey { // algorithms/Ed.PrivateKey|null[0] + sealed class Format : dev.whyoleg.cryptography.materials.key/KeyFormat { // algorithms/Ed.PrivateKey.Format|null[0] + final fun toString(): kotlin/String // algorithms/Ed.PrivateKey.Format.toString|toString(){}[0] + + final object DER : algorithms/Ed.PrivateKey.Format { // algorithms/Ed.PrivateKey.Format.DER|null[0] + final val name // algorithms/Ed.PrivateKey.Format.DER.name|{}name[0] + final fun (): kotlin/String // algorithms/Ed.PrivateKey.Format.DER.name.|(){}[0] + + final fun equals(kotlin/Any?): kotlin/Boolean // algorithms/Ed.PrivateKey.Format.DER.equals|equals(kotlin.Any?){}[0] + final fun hashCode(): kotlin/Int // algorithms/Ed.PrivateKey.Format.DER.hashCode|hashCode(){}[0] + } + + final object JWK : algorithms/Ed.PrivateKey.Format { // algorithms/Ed.PrivateKey.Format.JWK|null[0] + final val name // algorithms/Ed.PrivateKey.Format.JWK.name|{}name[0] + final fun (): kotlin/String // algorithms/Ed.PrivateKey.Format.JWK.name.|(){}[0] + + final fun equals(kotlin/Any?): kotlin/Boolean // algorithms/Ed.PrivateKey.Format.JWK.equals|equals(kotlin.Any?){}[0] + final fun hashCode(): kotlin/Int // algorithms/Ed.PrivateKey.Format.JWK.hashCode|hashCode(){}[0] + } + + final object PEM : algorithms/Ed.PrivateKey.Format { // algorithms/Ed.PrivateKey.Format.PEM|null[0] + final val name // algorithms/Ed.PrivateKey.Format.PEM.name|{}name[0] + final fun (): kotlin/String // algorithms/Ed.PrivateKey.Format.PEM.name.|(){}[0] + + final fun equals(kotlin/Any?): kotlin/Boolean // algorithms/Ed.PrivateKey.Format.PEM.equals|equals(kotlin.Any?){}[0] + final fun hashCode(): kotlin/Int // algorithms/Ed.PrivateKey.Format.PEM.hashCode|hashCode(){}[0] + } + + final object RAW : algorithms/Ed.PrivateKey.Format { // algorithms/Ed.PrivateKey.Format.RAW|null[0] + final val name // algorithms/Ed.PrivateKey.Format.RAW.name|{}name[0] + final fun (): kotlin/String // algorithms/Ed.PrivateKey.Format.RAW.name.|(){}[0] + + final fun equals(kotlin/Any?): kotlin/Boolean // algorithms/Ed.PrivateKey.Format.RAW.equals|equals(kotlin.Any?){}[0] + final fun hashCode(): kotlin/Int // algorithms/Ed.PrivateKey.Format.RAW.hashCode|hashCode(){}[0] + } + } + } + + abstract interface PublicKey : dev.whyoleg.cryptography.materials.key/EncodableKey { // algorithms/Ed.PublicKey|null[0] + sealed class Format : dev.whyoleg.cryptography.materials.key/KeyFormat { // algorithms/Ed.PublicKey.Format|null[0] + final fun toString(): kotlin/String // algorithms/Ed.PublicKey.Format.toString|toString(){}[0] + + final object DER : algorithms/Ed.PublicKey.Format { // algorithms/Ed.PublicKey.Format.DER|null[0] + final val name // algorithms/Ed.PublicKey.Format.DER.name|{}name[0] + final fun (): kotlin/String // algorithms/Ed.PublicKey.Format.DER.name.|(){}[0] + + final fun equals(kotlin/Any?): kotlin/Boolean // algorithms/Ed.PublicKey.Format.DER.equals|equals(kotlin.Any?){}[0] + final fun hashCode(): kotlin/Int // algorithms/Ed.PublicKey.Format.DER.hashCode|hashCode(){}[0] + } + + final object JWK : algorithms/Ed.PublicKey.Format { // algorithms/Ed.PublicKey.Format.JWK|null[0] + final val name // algorithms/Ed.PublicKey.Format.JWK.name|{}name[0] + final fun (): kotlin/String // algorithms/Ed.PublicKey.Format.JWK.name.|(){}[0] + + final fun equals(kotlin/Any?): kotlin/Boolean // algorithms/Ed.PublicKey.Format.JWK.equals|equals(kotlin.Any?){}[0] + final fun hashCode(): kotlin/Int // algorithms/Ed.PublicKey.Format.JWK.hashCode|hashCode(){}[0] + } + + final object PEM : algorithms/Ed.PublicKey.Format { // algorithms/Ed.PublicKey.Format.PEM|null[0] + final val name // algorithms/Ed.PublicKey.Format.PEM.name|{}name[0] + final fun (): kotlin/String // algorithms/Ed.PublicKey.Format.PEM.name.|(){}[0] + + final fun equals(kotlin/Any?): kotlin/Boolean // algorithms/Ed.PublicKey.Format.PEM.equals|equals(kotlin.Any?){}[0] + final fun hashCode(): kotlin/Int // algorithms/Ed.PublicKey.Format.PEM.hashCode|hashCode(){}[0] + } + + final object RAW : algorithms/Ed.PublicKey.Format { // algorithms/Ed.PublicKey.Format.RAW|null[0] + final val name // algorithms/Ed.PublicKey.Format.RAW.name|{}name[0] + final fun (): kotlin/String // algorithms/Ed.PublicKey.Format.RAW.name.|(){}[0] + + final fun equals(kotlin/Any?): kotlin/Boolean // algorithms/Ed.PublicKey.Format.RAW.equals|equals(kotlin.Any?){}[0] + final fun hashCode(): kotlin/Int // algorithms/Ed.PublicKey.Format.RAW.hashCode|hashCode(){}[0] + } + } + } + + final value class Curve { // algorithms/Ed.Curve|null[0] + constructor (kotlin/String) // algorithms/Ed.Curve.|(kotlin.String){}[0] + + final val name // algorithms/Ed.Curve.name|{}name[0] + final fun (): kotlin/String // algorithms/Ed.Curve.name.|(){}[0] + + final fun equals(kotlin/Any?): kotlin/Boolean // algorithms/Ed.Curve.equals|equals(kotlin.Any?){}[0] + final fun hashCode(): kotlin/Int // algorithms/Ed.Curve.hashCode|hashCode(){}[0] + final fun toString(): kotlin/String // algorithms/Ed.Curve.toString|toString(){}[0] + + final object Companion { // algorithms/Ed.Curve.Companion|null[0] + final val Ed25519 // algorithms/Ed.Curve.Companion.Ed25519|{}Ed25519[0] + final fun (): algorithms/Ed.Curve // algorithms/Ed.Curve.Companion.Ed25519.|(){}[0] + final val Ed448 // algorithms/Ed.Curve.Companion.Ed448|{}Ed448[0] + final fun (): algorithms/Ed.Curve // algorithms/Ed.Curve.Companion.Ed448.|(){}[0] + final val X25519 // algorithms/Ed.Curve.Companion.X25519|{}X25519[0] + final fun (): algorithms/Ed.Curve // algorithms/Ed.Curve.Companion.X25519.|(){}[0] + final val X448 // algorithms/Ed.Curve.Companion.X448|{}X448[0] + final fun (): algorithms/Ed.Curve // algorithms/Ed.Curve.Companion.X448.|(){}[0] + } + } +} + abstract interface <#A: dev.whyoleg.cryptography.algorithms/AES.Key> dev.whyoleg.cryptography.algorithms/AES : dev.whyoleg.cryptography/CryptographyAlgorithm { // dev.whyoleg.cryptography.algorithms/AES|null[0] abstract fun keyDecoder(): dev.whyoleg.cryptography.materials.key/KeyDecoder // dev.whyoleg.cryptography.algorithms/AES.keyDecoder|keyDecoder(){}[0] abstract fun keyGenerator(dev.whyoleg.cryptography/BinarySize = ...): dev.whyoleg.cryptography.materials.key/KeyGenerator<#A> // dev.whyoleg.cryptography.algorithms/AES.keyGenerator|keyGenerator(dev.whyoleg.cryptography.BinarySize){}[0] @@ -265,6 +376,14 @@ abstract interface <#A: dev.whyoleg.cryptography.algorithms/EC.PublicKey, #B: de final fun (): dev.whyoleg.cryptography.algorithms/EC.Curve // dev.whyoleg.cryptography.algorithms/EC.Curve.Companion.P384.|(){}[0] final val P521 // dev.whyoleg.cryptography.algorithms/EC.Curve.Companion.P521|{}P521[0] final fun (): dev.whyoleg.cryptography.algorithms/EC.Curve // dev.whyoleg.cryptography.algorithms/EC.Curve.Companion.P521.|(){}[0] + final val brainpoolP256r1 // dev.whyoleg.cryptography.algorithms/EC.Curve.Companion.brainpoolP256r1|{}brainpoolP256r1[0] + final fun (): dev.whyoleg.cryptography.algorithms/EC.Curve // dev.whyoleg.cryptography.algorithms/EC.Curve.Companion.brainpoolP256r1.|(){}[0] + final val brainpoolP384r1 // dev.whyoleg.cryptography.algorithms/EC.Curve.Companion.brainpoolP384r1|{}brainpoolP384r1[0] + final fun (): dev.whyoleg.cryptography.algorithms/EC.Curve // dev.whyoleg.cryptography.algorithms/EC.Curve.Companion.brainpoolP384r1.|(){}[0] + final val brainpoolP512r1 // dev.whyoleg.cryptography.algorithms/EC.Curve.Companion.brainpoolP512r1|{}brainpoolP512r1[0] + final fun (): dev.whyoleg.cryptography.algorithms/EC.Curve // dev.whyoleg.cryptography.algorithms/EC.Curve.Companion.brainpoolP512r1.|(){}[0] + final val secp256k1 // dev.whyoleg.cryptography.algorithms/EC.Curve.Companion.secp256k1|{}secp256k1[0] + final fun (): dev.whyoleg.cryptography.algorithms/EC.Curve // dev.whyoleg.cryptography.algorithms/EC.Curve.Companion.secp256k1.|(){}[0] } } } @@ -472,6 +591,40 @@ abstract interface <#A: dev.whyoleg.cryptography.materials.key/KeyFormat> dev.wh open suspend fun encodeToByteString(#A): kotlinx.io.bytestring/ByteString // dev.whyoleg.cryptography.materials.key/EncodableKey.encodeToByteString|encodeToByteString(1:0){}[0] } +abstract interface algorithms/EdDSA : algorithms/Ed { // algorithms/EdDSA|null[0] + open val id // algorithms/EdDSA.id|{}id[0] + open fun (): dev.whyoleg.cryptography/CryptographyAlgorithmId // algorithms/EdDSA.id.|(){}[0] + + abstract interface KeyPair : algorithms/Ed.KeyPair // algorithms/EdDSA.KeyPair|null[0] + + abstract interface PrivateKey : algorithms/Ed.PrivateKey { // algorithms/EdDSA.PrivateKey|null[0] + abstract fun signatureGenerator(): dev.whyoleg.cryptography.operations/SignatureGenerator // algorithms/EdDSA.PrivateKey.signatureGenerator|signatureGenerator(){}[0] + } + + abstract interface PublicKey : algorithms/Ed.PublicKey { // algorithms/EdDSA.PublicKey|null[0] + abstract fun signatureVerifier(): dev.whyoleg.cryptography.operations/SignatureVerifier // algorithms/EdDSA.PublicKey.signatureVerifier|signatureVerifier(){}[0] + } + + final object Companion : dev.whyoleg.cryptography/CryptographyAlgorithmId // algorithms/EdDSA.Companion|null[0] +} + +abstract interface algorithms/XDH : algorithms/Ed { // algorithms/XDH|null[0] + open val id // algorithms/XDH.id|{}id[0] + open fun (): dev.whyoleg.cryptography/CryptographyAlgorithmId // algorithms/XDH.id.|(){}[0] + + abstract interface KeyPair : algorithms/Ed.KeyPair // algorithms/XDH.KeyPair|null[0] + + abstract interface PrivateKey : algorithms/Ed.PrivateKey { // algorithms/XDH.PrivateKey|null[0] + abstract fun sharedSecretGenerator(): dev.whyoleg.cryptography.operations/SharedSecretGenerator // algorithms/XDH.PrivateKey.sharedSecretGenerator|sharedSecretGenerator(){}[0] + } + + abstract interface PublicKey : algorithms/Ed.PublicKey { // algorithms/XDH.PublicKey|null[0] + abstract fun sharedSecretGenerator(): dev.whyoleg.cryptography.operations/SharedSecretGenerator // algorithms/XDH.PublicKey.sharedSecretGenerator|sharedSecretGenerator(){}[0] + } + + final object Companion : dev.whyoleg.cryptography/CryptographyAlgorithmId // algorithms/XDH.Companion|null[0] +} + abstract interface dev.whyoleg.cryptography.algorithms/Digest : dev.whyoleg.cryptography/CryptographyAlgorithm { // dev.whyoleg.cryptography.algorithms/Digest|null[0] abstract val id // dev.whyoleg.cryptography.algorithms/Digest.id|{}id[0] abstract fun (): dev.whyoleg.cryptography/CryptographyAlgorithmId // dev.whyoleg.cryptography.algorithms/Digest.id.|(){}[0] From be5b98815ec117e5b8a4c90c7f105db43990dd5a Mon Sep 17 00:00:00 2001 From: waltkb <68587968+waltkb@users.noreply.github.com> Date: Wed, 19 Feb 2025 21:37:58 +0100 Subject: [PATCH 06/12] Replace mentions of secp256k1 --- .../src/commonMain/kotlin/support.kt | 2 +- .../commonMain/kotlin/compatibility/EcCompatibilityTest.kt | 2 +- .../src/commonMain/kotlin/default/EcdsaTest.kt | 4 ++-- cryptography-providers/jdk/README.md | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/cryptography-providers-tests-api/src/commonMain/kotlin/support.kt b/cryptography-providers-tests-api/src/commonMain/kotlin/support.kt index 4d65d83d..2c063e91 100644 --- a/cryptography-providers-tests-api/src/commonMain/kotlin/support.kt +++ b/cryptography-providers-tests-api/src/commonMain/kotlin/support.kt @@ -85,7 +85,7 @@ fun AlgorithmTestScope.supportsEncryption(): Boolean = supports { fun AlgorithmTestScope>.supportsCurve(curve: EC.Curve): Boolean = supports { when { // JDK default, WebCrypto and Apple doesn't support secp256k1 - curve.name == "secp256k1" && ( + curve == EC.Curve.secp256k1 && ( provider.isJdkDefault || provider.isWebCrypto || provider.isApple ) -> "ECDSA ${curve.name}" else -> null diff --git a/cryptography-providers-tests/src/commonMain/kotlin/compatibility/EcCompatibilityTest.kt b/cryptography-providers-tests/src/commonMain/kotlin/compatibility/EcCompatibilityTest.kt index f57206d0..e09509d6 100644 --- a/cryptography-providers-tests/src/commonMain/kotlin/compatibility/EcCompatibilityTest.kt +++ b/cryptography-providers-tests/src/commonMain/kotlin/compatibility/EcCompatibilityTest.kt @@ -41,7 +41,7 @@ abstract class EcCompatibilityTest Unit) { - generate(block, EC.Curve.P256, EC.Curve.P384, EC.Curve.P521, EC.Curve("secp256k1")) + generate(block, EC.Curve.P256, EC.Curve.P384, EC.Curve.P521, EC.Curve.secp256k1) } protected suspend fun CompatibilityTestScope.generateKeys( diff --git a/cryptography-providers-tests/src/commonMain/kotlin/default/EcdsaTest.kt b/cryptography-providers-tests/src/commonMain/kotlin/default/EcdsaTest.kt index e8551f2c..fbdabbce 100644 --- a/cryptography-providers-tests/src/commonMain/kotlin/default/EcdsaTest.kt +++ b/cryptography-providers-tests/src/commonMain/kotlin/default/EcdsaTest.kt @@ -35,7 +35,7 @@ abstract class EcdsaTest(provider: CryptographyProvider) : AlgorithmTest( EcdsaSize(EC.Curve.P256, 64, listOf(68, 69, 70, 71, 72), 91, listOf(67, 138, 150)), EcdsaSize(EC.Curve.P384, 96, listOf(100, 101, 102, 103, 104), 120, listOf(80, 185, 194)), EcdsaSize(EC.Curve.P521, 132, listOf(136, 137, 138, 139), 158, listOf(98, 241, 250)), - EcdsaSize(EC.Curve("secp256k1"), 64, listOf(68, 69, 70, 71, 72), 88, listOf(135, 144)), + EcdsaSize(EC.Curve.secp256k1, 64, listOf(68, 69, 70, 71, 72), 88, listOf(135, 144)), ).forEach { (curve, rawSignatureSize, derSignatureSizes, publicKeySize, privateKeySizes) -> if (!supportsCurve(curve)) return@forEach @@ -93,7 +93,7 @@ abstract class EcdsaTest(provider: CryptographyProvider) : AlgorithmTest( EC.Curve.P256, EC.Curve.P384, EC.Curve.P521, - EC.Curve("secp256k1"), + EC.Curve.secp256k1, ).forEach { curve -> if (!supportsCurve(curve)) return@forEach diff --git a/cryptography-providers/jdk/README.md b/cryptography-providers/jdk/README.md index 797667d4..1c875061 100644 --- a/cryptography-providers/jdk/README.md +++ b/cryptography-providers/jdk/README.md @@ -11,7 +11,7 @@ For supported targets and algorithms, please consult [Supported primitives secti ## Custom Java providers Some specific algorithms (SHA3 family of digests on JDK 8) or parameters (`secp256k1` curve for ECDSA) could be not supported by default JDK -provider, but it doesn't mean, that you can not use them with `cryptography-kotlin`. +provider, but it doesn't mean, that you cannot use them with `cryptography-kotlin`. There is a possibility to create [CryptographyProvider][CryptographyProvider] from [java.util.Provider](https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/security/Provider.html), f.e. using [BouncyCastle](https://www.bouncycastle.org): From 5469b0f54c8c808d5c5bf902d8a95a2702f50c88 Mon Sep 17 00:00:00 2001 From: waltkb <68587968+waltkb@users.noreply.github.com> Date: Wed, 19 Feb 2025 21:38:12 +0100 Subject: [PATCH 07/12] Update API for cryptography-core --- cryptography-core/api/cryptography-core.api | 4 ++++ cryptography-core/api/cryptography-core.klib.api | 8 ++++++++ 2 files changed, 12 insertions(+) diff --git a/cryptography-core/api/cryptography-core.api b/cryptography-core/api/cryptography-core.api index 327b419d..ae4712bf 100644 --- a/cryptography-core/api/cryptography-core.api +++ b/cryptography-core/api/cryptography-core.api @@ -253,9 +253,13 @@ public final class dev/whyoleg/cryptography/algorithms/EC$Curve { } public final class dev/whyoleg/cryptography/algorithms/EC$Curve$Companion { + public final fun getBrainpoolP256r1-pVITJAk ()Ljava/lang/String; + public final fun getBrainpoolP384r1-pVITJAk ()Ljava/lang/String; + public final fun getBrainpoolP512r1-pVITJAk ()Ljava/lang/String; public final fun getP256-pVITJAk ()Ljava/lang/String; public final fun getP384-pVITJAk ()Ljava/lang/String; public final fun getP521-pVITJAk ()Ljava/lang/String; + public final fun getSecp256k1-pVITJAk ()Ljava/lang/String; } public abstract interface class dev/whyoleg/cryptography/algorithms/EC$KeyPair : dev/whyoleg/cryptography/materials/key/Key { diff --git a/cryptography-core/api/cryptography-core.klib.api b/cryptography-core/api/cryptography-core.klib.api index 4d43f5b9..1dda659d 100644 --- a/cryptography-core/api/cryptography-core.klib.api +++ b/cryptography-core/api/cryptography-core.klib.api @@ -265,6 +265,14 @@ abstract interface <#A: dev.whyoleg.cryptography.algorithms/EC.PublicKey, #B: de final fun (): dev.whyoleg.cryptography.algorithms/EC.Curve // dev.whyoleg.cryptography.algorithms/EC.Curve.Companion.P384.|(){}[0] final val P521 // dev.whyoleg.cryptography.algorithms/EC.Curve.Companion.P521|{}P521[0] final fun (): dev.whyoleg.cryptography.algorithms/EC.Curve // dev.whyoleg.cryptography.algorithms/EC.Curve.Companion.P521.|(){}[0] + final val brainpoolP256r1 // dev.whyoleg.cryptography.algorithms/EC.Curve.Companion.brainpoolP256r1|{}brainpoolP256r1[0] + final fun (): dev.whyoleg.cryptography.algorithms/EC.Curve // dev.whyoleg.cryptography.algorithms/EC.Curve.Companion.brainpoolP256r1.|(){}[0] + final val brainpoolP384r1 // dev.whyoleg.cryptography.algorithms/EC.Curve.Companion.brainpoolP384r1|{}brainpoolP384r1[0] + final fun (): dev.whyoleg.cryptography.algorithms/EC.Curve // dev.whyoleg.cryptography.algorithms/EC.Curve.Companion.brainpoolP384r1.|(){}[0] + final val brainpoolP512r1 // dev.whyoleg.cryptography.algorithms/EC.Curve.Companion.brainpoolP512r1|{}brainpoolP512r1[0] + final fun (): dev.whyoleg.cryptography.algorithms/EC.Curve // dev.whyoleg.cryptography.algorithms/EC.Curve.Companion.brainpoolP512r1.|(){}[0] + final val secp256k1 // dev.whyoleg.cryptography.algorithms/EC.Curve.Companion.secp256k1|{}secp256k1[0] + final fun (): dev.whyoleg.cryptography.algorithms/EC.Curve // dev.whyoleg.cryptography.algorithms/EC.Curve.Companion.secp256k1.|(){}[0] } } } From ce0c17c3a6a972ac3a5957820c5f8ea048158c7e Mon Sep 17 00:00:00 2001 From: waltkb <68587968+waltkb@users.noreply.github.com> Date: Wed, 19 Feb 2025 21:52:41 +0100 Subject: [PATCH 08/12] Change package name for Ed --- cryptography-core/src/commonMain/kotlin/algorithms/Ed.kt | 2 +- .../jdk/src/jvmMain/kotlin/algorithms/JdkEd.kt | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/cryptography-core/src/commonMain/kotlin/algorithms/Ed.kt b/cryptography-core/src/commonMain/kotlin/algorithms/Ed.kt index 3f3bf50f..d9006371 100644 --- a/cryptography-core/src/commonMain/kotlin/algorithms/Ed.kt +++ b/cryptography-core/src/commonMain/kotlin/algorithms/Ed.kt @@ -1,4 +1,4 @@ -package algorithms +package dev.whyoleg.cryptography.algorithm import dev.whyoleg.cryptography.* import dev.whyoleg.cryptography.materials.key.* diff --git a/cryptography-providers/jdk/src/jvmMain/kotlin/algorithms/JdkEd.kt b/cryptography-providers/jdk/src/jvmMain/kotlin/algorithms/JdkEd.kt index a9825768..b072cf87 100644 --- a/cryptography-providers/jdk/src/jvmMain/kotlin/algorithms/JdkEd.kt +++ b/cryptography-providers/jdk/src/jvmMain/kotlin/algorithms/JdkEd.kt @@ -1,5 +1,6 @@ -package algorithms +package dev.whyoleg.cryptography.providers.jdk.algorithms +import dev.whyoleg.cryptography.algorithm.Ed import dev.whyoleg.cryptography.materials.key.KeyDecoder import dev.whyoleg.cryptography.materials.key.KeyGenerator import dev.whyoleg.cryptography.providers.jdk.JKeyPair From 7495a8f9d9a4e7fb69b10e94e6b561e2c4514526 Mon Sep 17 00:00:00 2001 From: waltkb <68587968+waltkb@users.noreply.github.com> Date: Thu, 17 Apr 2025 22:01:44 +0200 Subject: [PATCH 09/12] Add Brainpool curves to EcCompatibilityTest.kt --- .../commonMain/kotlin/compatibility/EcCompatibilityTest.kt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/cryptography-providers-tests/src/commonMain/kotlin/compatibility/EcCompatibilityTest.kt b/cryptography-providers-tests/src/commonMain/kotlin/compatibility/EcCompatibilityTest.kt index e09509d6..d54dbf6d 100644 --- a/cryptography-providers-tests/src/commonMain/kotlin/compatibility/EcCompatibilityTest.kt +++ b/cryptography-providers-tests/src/commonMain/kotlin/compatibility/EcCompatibilityTest.kt @@ -41,7 +41,11 @@ abstract class EcCompatibilityTest Unit) { - generate(block, EC.Curve.P256, EC.Curve.P384, EC.Curve.P521, EC.Curve.secp256k1) + generate(block, + EC.Curve.P256, EC.Curve.P384, EC.Curve.P521, + EC.Curve.secp256k1, + EC.Curve.brainpoolP256r1, EC.Curve.brainpoolP384r1, EC.Curve.brainpoolP512r1, + ) } protected suspend fun CompatibilityTestScope.generateKeys( From b62df0a3a44af2ca7d445b21e8e182fdadca5024 Mon Sep 17 00:00:00 2001 From: waltkb <68587968+waltkb@users.noreply.github.com> Date: Thu, 17 Apr 2025 22:02:11 +0200 Subject: [PATCH 10/12] Update EcdsaTest.kt --- .../commonMain/kotlin/default/EcdsaTest.kt | 112 +++++++++++++++--- 1 file changed, 94 insertions(+), 18 deletions(-) diff --git a/cryptography-providers-tests/src/commonMain/kotlin/default/EcdsaTest.kt b/cryptography-providers-tests/src/commonMain/kotlin/default/EcdsaTest.kt index fbdabbce..4008cc63 100644 --- a/cryptography-providers-tests/src/commonMain/kotlin/default/EcdsaTest.kt +++ b/cryptography-providers-tests/src/commonMain/kotlin/default/EcdsaTest.kt @@ -24,7 +24,7 @@ abstract class EcdsaTest(provider: CryptographyProvider) : AlgorithmTest( data class EcdsaSize( val curve: EC.Curve, val rawSignatureSize: Int, - val derSignatureSizes: List, + val derSignatureSizes: IntRange, val publicKeySize: Int, val privateKeySizes: List, ) @@ -32,32 +32,86 @@ abstract class EcdsaTest(provider: CryptographyProvider) : AlgorithmTest( @Test fun testSizes() = testWithAlgorithm { listOf( - EcdsaSize(EC.Curve.P256, 64, listOf(68, 69, 70, 71, 72), 91, listOf(67, 138, 150)), - EcdsaSize(EC.Curve.P384, 96, listOf(100, 101, 102, 103, 104), 120, listOf(80, 185, 194)), - EcdsaSize(EC.Curve.P521, 132, listOf(136, 137, 138, 139), 158, listOf(98, 241, 250)), - EcdsaSize(EC.Curve.secp256k1, 64, listOf(68, 69, 70, 71, 72), 88, listOf(135, 144)), + // NIST curves + EcdsaSize(EC.Curve.P256, 64, 68.rangeTo(72), 91, listOf(67, 138, 150)), + EcdsaSize(EC.Curve.P384, 96, 100.rangeTo(104), 120, listOf(80, 185, 194)), + EcdsaSize(EC.Curve.P521, 132, 136.rangeTo(139), 158, listOf(98, 241, 250)), + + // Note "private key sizes": smaller = openssl, larger = BouncyCastle + + // SECP256k1 + EcdsaSize(EC.Curve.secp256k1, 64, 68.rangeTo(72), 88, listOf(135, 144)), + + // Brainpool curves + EcdsaSize(EC.Curve.brainpoolP256r1, 64, 68.rangeTo(72), 92, listOf(139, 152)), + EcdsaSize(EC.Curve.brainpoolP384r1, 96, 100.rangeTo(104), 124, listOf(189, 202)), + EcdsaSize( + EC.Curve.brainpoolP512r1, + 128, + 132.rangeTo(139), + 158, + listOf(239, 252) + ) // Raw 128, DER sig slightly larger; PubKey ~154; PrivKey ~P521 + + ).forEach { (curve, rawSignatureSize, derSignatureSizes, publicKeySize, privateKeySizes) -> - if (!supportsCurve(curve)) return@forEach + if (!supportsCurve(curve)) { + println("Skipping size test for unsupported curve: ${curve.name}") + return@forEach + } + println("\nRunning size test for curve: ${curve.name}") val keyPair = algorithm.keyPairGenerator(curve).generateKey() - assertEquals(publicKeySize, keyPair.publicKey.encodeToByteString(EC.PublicKey.Format.DER).size) - assertContains(privateKeySizes, keyPair.privateKey.encodeToByteString(EC.PrivateKey.Format.DER).size) + val actualPublicKeySize = keyPair.publicKey.encodeToByteString(EC.PublicKey.Format.DER).size + println("Got ${curve.name} public key size: $actualPublicKeySize (expected $publicKeySize)") + assertEquals( + publicKeySize, + actualPublicKeySize, + "Public key size mismatch for ${curve.name}, expected: $publicKeySize, but got $actualPublicKeySize" + ) + val actualPrivateKeySize = keyPair.privateKey.encodeToByteString(EC.PrivateKey.Format.DER).size + println("Got ${curve.name} private key size: $actualPrivateKeySize (allowed $privateKeySizes)") + assertContains( + privateKeySizes, + actualPrivateKeySize, + "Private key size mismatch for ${curve.name}, expected one of $privateKeySizes, but got $actualPrivateKeySize" + ) generateDigests { digest, _ -> - if (!supportsDigest(digest)) return@generateDigests + if (!supportsDigest(digest)) { + println("Skipping digest $digest for curve ${curve.name}") + return@generateDigests + } // RAW signature run { val verifier = keyPair.publicKey.signatureVerifier(digest, ECDSA.SignatureFormat.RAW) keyPair.privateKey.signatureGenerator(digest, ECDSA.SignatureFormat.RAW).run { - assertEquals(rawSignatureSize, generateSignature(ByteArray(0)).size) + val sigEmpty = generateSignature(ByteArray(0)) + assertEquals( + rawSignatureSize, + sigEmpty.size, + "RAW signature size mismatch for empty data on ${curve.name} / ${digest.name}" + ) + assertTrue( + verifier.tryVerifySignature(ByteArray(0), sigEmpty), + "RAW signature verification failed for empty data on ${curve.name} / ${digest.name}" + ) + repeat(8) { n -> val size = 10.0.pow(n).toInt() val data = CryptographyRandom.nextBytes(size) val signature = generateSignature(data) - assertEquals(rawSignatureSize, signature.size) - assertTrue(verifier.tryVerifySignature(data, signature)) + assertEquals( + rawSignatureSize, + signature.size, + "RAW signature size mismatch for data size $size on ${curve.name} / ${digest.name}" + ) + assertTrue( + verifier.tryVerifySignature(data, signature), + "RAW signature verification failed for data size $size on ${curve.name} / ${digest.name}" + ) } } } @@ -68,7 +122,12 @@ abstract class EcdsaTest(provider: CryptographyProvider) : AlgorithmTest( fun assertSignatureSize(signature: ByteArray) { if (signature.size in derSignatureSizes) return // enhance a message with Base64 encoded signature - assertContains(derSignatureSizes, signature.size, "DER: ${Base64.encode(signature)}") + + assertContains( + derSignatureSizes, signature.size, "DER signature size mismatch on ${curve.name} / ${digest.name}. " + + "Expected one of $derSignatureSizes, got ${signature.size}. " + + "Signature (Base64): ${Base64.encode(signature)}" + ) } assertSignatureSize(generateSignature(ByteArray(0))) @@ -77,7 +136,10 @@ abstract class EcdsaTest(provider: CryptographyProvider) : AlgorithmTest( val data = CryptographyRandom.nextBytes(size) val signature = generateSignature(data) assertSignatureSize(signature) - assertTrue(verifier.tryVerifySignature(data, signature)) + assertTrue( + verifier.tryVerifySignature(data, signature), + "DER signature verification failed for data size $size on ${curve.name} / ${digest.name}" + ) } } } @@ -87,27 +149,41 @@ abstract class EcdsaTest(provider: CryptographyProvider) : AlgorithmTest( @Test fun testFunctions() = testWithAlgorithm { - if (!supportsFunctions()) return@testWithAlgorithm + if (!supportsFunctions()) { + println("Skipping function test because functions are not supported by provider") + return@testWithAlgorithm + } listOf( EC.Curve.P256, EC.Curve.P384, EC.Curve.P521, EC.Curve.secp256k1, + EC.Curve.brainpoolP256r1, + EC.Curve.brainpoolP384r1, + EC.Curve.brainpoolP512r1, ).forEach { curve -> - if (!supportsCurve(curve)) return@forEach + if (!supportsCurve(curve)) { + println("Skipping function test for unsupported curve: ${curve.name}") + return@forEach + } + println("Running function test for curve: ${curve.name}") val keyPair = algorithm.keyPairGenerator(curve).generateKey() generateDigests { digest, _ -> - if (!supportsDigest(digest)) return@generateDigests + if (!supportsDigest(digest)) { + println("Skipping digest $digest for curve ${curve.name}") + return@generateDigests + } ECDSA.SignatureFormat.entries.forEach { format -> + println("Testing format $format for ${curve.name} / ${digest.name}") val signatureGenerator = keyPair.privateKey.signatureGenerator(digest, format) val signatureVerifier = keyPair.publicKey.signatureVerifier(digest, format) repeat(10) { - val size = CryptographyRandom.nextInt(20000) + val size = CryptographyRandom.nextInt(1024, 20000) // Ensure non-trivial size val data = ByteString(CryptographyRandom.nextBytes(size)) assertSignaturesViaFunction(signatureGenerator, signatureVerifier, data) } From 4114959b4758a3c1bd168adf54a0c9712b35d7f3 Mon Sep 17 00:00:00 2001 From: waltkb <68587968+waltkb@users.noreply.github.com> Date: Thu, 17 Apr 2025 22:02:23 +0200 Subject: [PATCH 11/12] Add brainpool exclusion to support.kt --- .../src/commonMain/kotlin/support.kt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/cryptography-providers-tests-api/src/commonMain/kotlin/support.kt b/cryptography-providers-tests-api/src/commonMain/kotlin/support.kt index 2c063e91..3a33bfe4 100644 --- a/cryptography-providers-tests-api/src/commonMain/kotlin/support.kt +++ b/cryptography-providers-tests-api/src/commonMain/kotlin/support.kt @@ -84,10 +84,11 @@ fun AlgorithmTestScope.supportsEncryption(): Boolean = supports { fun AlgorithmTestScope>.supportsCurve(curve: EC.Curve): Boolean = supports { when { - // JDK default, WebCrypto and Apple doesn't support secp256k1 - curve == EC.Curve.secp256k1 && ( + // JDK default/WebCrypto/Apple don't support secp256k1 or brainpool + curve in listOf(EC.Curve.secp256k1, EC.Curve.brainpoolP256r1, EC.Curve.brainpoolP384r1, EC.Curve.brainpoolP512r1) && ( provider.isJdkDefault || provider.isWebCrypto || provider.isApple ) -> "ECDSA ${curve.name}" + else -> null } } From 2d84bafe7aa9bbb049d7c601093d68d3a26b1463 Mon Sep 17 00:00:00 2001 From: waltkb <68587968+waltkb@users.noreply.github.com> Date: Thu, 17 Apr 2025 22:38:15 +0200 Subject: [PATCH 12/12] Fix package names --- .../src/commonMain/kotlin/algorithms/Ed.kt | 2 +- .../src/commonMain/kotlin/algorithms/EdDSA.kt | 8 +++----- .../src/commonMain/kotlin/algorithms/XDH.kt | 2 +- .../src/jvmMain/kotlin/JdkCryptographyProvider.kt | 1 - .../jdk/src/jvmMain/kotlin/algorithms/JdkEd.kt | 2 +- .../jdk/src/jvmMain/kotlin/algorithms/JdkEdDSA.kt | 14 +++++--------- .../jdk/src/jvmMain/kotlin/algorithms/JdkXDH.kt | 3 ++- 7 files changed, 13 insertions(+), 19 deletions(-) diff --git a/cryptography-core/src/commonMain/kotlin/algorithms/Ed.kt b/cryptography-core/src/commonMain/kotlin/algorithms/Ed.kt index d9006371..56e57e2e 100644 --- a/cryptography-core/src/commonMain/kotlin/algorithms/Ed.kt +++ b/cryptography-core/src/commonMain/kotlin/algorithms/Ed.kt @@ -1,4 +1,4 @@ -package dev.whyoleg.cryptography.algorithm +package dev.whyoleg.cryptography.algorithms import dev.whyoleg.cryptography.* import dev.whyoleg.cryptography.materials.key.* diff --git a/cryptography-core/src/commonMain/kotlin/algorithms/EdDSA.kt b/cryptography-core/src/commonMain/kotlin/algorithms/EdDSA.kt index 489be029..75e441f5 100644 --- a/cryptography-core/src/commonMain/kotlin/algorithms/EdDSA.kt +++ b/cryptography-core/src/commonMain/kotlin/algorithms/EdDSA.kt @@ -1,9 +1,7 @@ -package algorithms +package dev.whyoleg.cryptography.algorithms -import dev.whyoleg.cryptography.CryptographyAlgorithmId -import dev.whyoleg.cryptography.CryptographyProviderApi -import dev.whyoleg.cryptography.operations.SignatureGenerator -import dev.whyoleg.cryptography.operations.SignatureVerifier +import dev.whyoleg.cryptography.* +import dev.whyoleg.cryptography.operations.* @SubclassOptInRequired(CryptographyProviderApi::class) public interface EdDSA : Ed { diff --git a/cryptography-core/src/commonMain/kotlin/algorithms/XDH.kt b/cryptography-core/src/commonMain/kotlin/algorithms/XDH.kt index 91a0ca77..616f4f85 100644 --- a/cryptography-core/src/commonMain/kotlin/algorithms/XDH.kt +++ b/cryptography-core/src/commonMain/kotlin/algorithms/XDH.kt @@ -1,4 +1,4 @@ -package algorithms +package dev.whyoleg.cryptography.algorithms import dev.whyoleg.cryptography.CryptographyAlgorithmId import dev.whyoleg.cryptography.CryptographyProviderApi diff --git a/cryptography-providers/jdk/src/jvmMain/kotlin/JdkCryptographyProvider.kt b/cryptography-providers/jdk/src/jvmMain/kotlin/JdkCryptographyProvider.kt index 08bc3725..16ad4dca 100644 --- a/cryptography-providers/jdk/src/jvmMain/kotlin/JdkCryptographyProvider.kt +++ b/cryptography-providers/jdk/src/jvmMain/kotlin/JdkCryptographyProvider.kt @@ -4,7 +4,6 @@ package dev.whyoleg.cryptography.providers.jdk -import algorithms.* import dev.whyoleg.cryptography.* import dev.whyoleg.cryptography.algorithms.* import dev.whyoleg.cryptography.providers.jdk.algorithms.* diff --git a/cryptography-providers/jdk/src/jvmMain/kotlin/algorithms/JdkEd.kt b/cryptography-providers/jdk/src/jvmMain/kotlin/algorithms/JdkEd.kt index b072cf87..e5fda400 100644 --- a/cryptography-providers/jdk/src/jvmMain/kotlin/algorithms/JdkEd.kt +++ b/cryptography-providers/jdk/src/jvmMain/kotlin/algorithms/JdkEd.kt @@ -1,6 +1,6 @@ package dev.whyoleg.cryptography.providers.jdk.algorithms -import dev.whyoleg.cryptography.algorithm.Ed +import dev.whyoleg.cryptography.algorithms.Ed import dev.whyoleg.cryptography.materials.key.KeyDecoder import dev.whyoleg.cryptography.materials.key.KeyGenerator import dev.whyoleg.cryptography.providers.jdk.JKeyPair diff --git a/cryptography-providers/jdk/src/jvmMain/kotlin/algorithms/JdkEdDSA.kt b/cryptography-providers/jdk/src/jvmMain/kotlin/algorithms/JdkEdDSA.kt index 9e0b9455..141cfcdf 100644 --- a/cryptography-providers/jdk/src/jvmMain/kotlin/algorithms/JdkEdDSA.kt +++ b/cryptography-providers/jdk/src/jvmMain/kotlin/algorithms/JdkEdDSA.kt @@ -1,13 +1,9 @@ -package algorithms +package dev.whyoleg.cryptography.providers.jdk.algorithms -import dev.whyoleg.cryptography.operations.SignatureGenerator -import dev.whyoleg.cryptography.operations.SignatureVerifier -import dev.whyoleg.cryptography.providers.jdk.JKeyPair -import dev.whyoleg.cryptography.providers.jdk.JPrivateKey -import dev.whyoleg.cryptography.providers.jdk.JPublicKey -import dev.whyoleg.cryptography.providers.jdk.JdkCryptographyState -import dev.whyoleg.cryptography.providers.jdk.operations.JdkSignatureGenerator -import dev.whyoleg.cryptography.providers.jdk.operations.JdkSignatureVerifier +import dev.whyoleg.cryptography.algorithms.EdDSA +import dev.whyoleg.cryptography.operations.* +import dev.whyoleg.cryptography.providers.jdk.* +import dev.whyoleg.cryptography.providers.jdk.operations.* internal class JdkEdDSA(state: JdkCryptographyState) : JdkEd(state), EdDSA { override fun JPublicKey.convert(): EdDSA.PublicKey = EdDsaPublicKey(state, this) diff --git a/cryptography-providers/jdk/src/jvmMain/kotlin/algorithms/JdkXDH.kt b/cryptography-providers/jdk/src/jvmMain/kotlin/algorithms/JdkXDH.kt index 799e2924..e6edccd0 100644 --- a/cryptography-providers/jdk/src/jvmMain/kotlin/algorithms/JdkXDH.kt +++ b/cryptography-providers/jdk/src/jvmMain/kotlin/algorithms/JdkXDH.kt @@ -1,5 +1,6 @@ -package algorithms +package dev.whyoleg.cryptography.providers.jdk.algorithms +import dev.whyoleg.cryptography.algorithms.XDH import dev.whyoleg.cryptography.operations.SharedSecretGenerator import dev.whyoleg.cryptography.providers.jdk.JKeyPair import dev.whyoleg.cryptography.providers.jdk.JPrivateKey