diff --git a/.github/workflows/e2e-tests.yml b/.github/workflows/e2e-tests.yml index c2dced931..ff1eef05f 100644 --- a/.github/workflows/e2e-tests.yml +++ b/.github/workflows/e2e-tests.yml @@ -29,9 +29,6 @@ on: required: false description: Authorization key default: 1gnp5fzLTwNBvLBXLk9THLgxe9SLoh+7 - pull_request: - branches: - - main push: branches: - main diff --git a/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/apollo/ApolloImpl.kt b/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/apollo/ApolloImpl.kt index ada17708c..00516f7c0 100644 --- a/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/apollo/ApolloImpl.kt +++ b/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/apollo/ApolloImpl.kt @@ -128,7 +128,11 @@ class ApolloImpl : Apollo { val hdKey = HDKey(seedByteArray, 0, 0) val derivedHdKey = hdKey.derive(derivationPath) - return Secp256k1PrivateKey(derivedHdKey.getKMMSecp256k1PrivateKey().raw) + val private = Secp256k1PrivateKey(derivedHdKey.getKMMSecp256k1PrivateKey().raw) + private.keySpecification[SeedKey().property] = seed + private.keySpecification[DerivationPathKey().property] = derivationPath + private.keySpecification[IndexKey().property] = "0" + return private } } } diff --git a/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/apollo/utils/Secp256k1PrivateKey.kt b/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/apollo/utils/Secp256k1PrivateKey.kt index c6e9d2451..c01400900 100644 --- a/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/apollo/utils/Secp256k1PrivateKey.kt +++ b/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/apollo/utils/Secp256k1PrivateKey.kt @@ -1,11 +1,15 @@ package io.iohk.atala.prism.walletsdk.apollo.utils import io.iohk.atala.prism.apollo.base64.base64UrlEncoded +import io.iohk.atala.prism.apollo.derivation.DerivationPath +import io.iohk.atala.prism.apollo.derivation.HDKey import io.iohk.atala.prism.apollo.utils.KMMECSecp256k1PrivateKey +import io.iohk.atala.prism.walletsdk.apollo.helpers.BytesOps import io.iohk.atala.prism.walletsdk.domain.models.Curve import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.CurveKey import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.CurvePointXKey import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.CurvePointYKey +import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.DerivableKey import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.ExportableKey import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.JWK import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.KeyTypes @@ -13,10 +17,16 @@ import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.PEMKey import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.PEMKeyType import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.PrivateKey import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.PublicKey +import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.SeedKey import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.SignableKey import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.StorableKey -class Secp256k1PrivateKey(nativeValue: ByteArray) : PrivateKey(), SignableKey, StorableKey, ExportableKey { +class Secp256k1PrivateKey(nativeValue: ByteArray) : + PrivateKey(), + SignableKey, + StorableKey, + ExportableKey, + DerivableKey { override val type: KeyTypes = KeyTypes.EC override val keySpecification: MutableMap = mutableMapOf() override val size: Int @@ -42,6 +52,7 @@ class Secp256k1PrivateKey(nativeValue: ByteArray) : PrivateKey(), SignableKey, S keyData = raw ).pemEncoded() } + override fun getJwk(): JWK { return JWK( kty = "OKP", @@ -50,7 +61,6 @@ class Secp256k1PrivateKey(nativeValue: ByteArray) : PrivateKey(), SignableKey, S y = getProperty(CurvePointYKey().property).base64UrlEncoded ) } - override fun jwkWithKid(kid: String): JWK { return JWK( kty = "OKP", @@ -65,4 +75,14 @@ class Secp256k1PrivateKey(nativeValue: ByteArray) : PrivateKey(), SignableKey, S get() = raw override val restorationIdentifier: String get() = "secp256k1+priv" + + override fun derive(derivationPath: DerivationPath): PrivateKey { + val seed = getProperty(SeedKey().property) + + val seedByteArray = BytesOps.hexToBytes(seed) + + val hdKey = HDKey(seedByteArray, 0, 0) + val derivedHdKey = hdKey.derive(derivationPath.toString()) + return Secp256k1PrivateKey(derivedHdKey.getKMMSecp256k1PrivateKey().raw) + } } diff --git a/atala-prism-sdk/src/commonTest/kotlin/io/iohk/atala/prism/walletsdk/apollo/ApolloTests.kt b/atala-prism-sdk/src/commonTest/kotlin/io/iohk/atala/prism/walletsdk/apollo/ApolloTests.kt index 8b462a775..3cb70f811 100644 --- a/atala-prism-sdk/src/commonTest/kotlin/io/iohk/atala/prism/walletsdk/apollo/ApolloTests.kt +++ b/atala-prism-sdk/src/commonTest/kotlin/io/iohk/atala/prism/walletsdk/apollo/ApolloTests.kt @@ -1,6 +1,7 @@ package io.iohk.atala.prism.walletsdk.apollo import io.iohk.atala.prism.apollo.base64.base64UrlEncoded +import io.iohk.atala.prism.apollo.derivation.DerivationPath import io.iohk.atala.prism.apollo.derivation.Mnemonic import io.iohk.atala.prism.apollo.derivation.MnemonicHelper import io.iohk.atala.prism.apollo.utils.ECConfig @@ -19,8 +20,12 @@ import io.iohk.atala.prism.walletsdk.domain.buildingblocks.Apollo import io.iohk.atala.prism.walletsdk.domain.models.Curve import io.iohk.atala.prism.walletsdk.domain.models.KeyCurve import io.iohk.atala.prism.walletsdk.domain.models.Seed +import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.CurveKey import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.KeyPair +import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.KeyTypes +import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.SeedKey import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.StorableKey +import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.TypeKey import kotlinx.serialization.json.Json import org.junit.Assert.assertNotEquals import org.junit.Before @@ -100,6 +105,26 @@ class ApolloTests { assertTrue((keyPair.privateKey as Secp256k1PrivateKey).isExportable()) } + @Test + fun testDerivePrivateKey_whenSecp256k1_thenWorksAsExpected() { + val path = "m/0'/0'/0'" + + val seed = Seed(Mnemonic.createRandomSeed()) + + val properties: MutableMap = mutableMapOf() + properties[TypeKey().property] = KeyTypes.EC + properties[SeedKey().property] = BytesOps.bytesToHex(seed.value) + properties[CurveKey().property] = Curve.SECP256K1.value + + val privateKey = apollo.createPrivateKey(properties) as Secp256k1PrivateKey + privateKey.derive(DerivationPath.fromPath(path)) + assertTrue(privateKey.isDerivable()) + + val ed25519KeyPair = Ed25519KeyPair.generateKeyPair() + val ed25519PrivateKey = ed25519KeyPair.privateKey as Ed25519PrivateKey + assertFalse(ed25519PrivateKey.isDerivable()) + } + @Test fun testCreateKeyPair_whenNoSeedAndKeyCurveEd25519_thenPrivateKeyLengthIsCorrect() { val keyPair = Ed25519KeyPair.generateKeyPair()