From a9675b131f01a270e3c840457b1d26772970addd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Francisco=20Javier=20Ribo=CC=81=20Labrador?= Date: Wed, 10 Apr 2024 12:55:45 +0200 Subject: [PATCH 01/39] fix: Adding the uniffy defrinition file and change the folder paths for the correct ones --- apollo/build.gradle.kts | 83 ++++++++++++++++++-- apollo/src/nativeInterop/cinterop/uniffi.def | 13 +++ 2 files changed, 90 insertions(+), 6 deletions(-) create mode 100644 apollo/src/nativeInterop/cinterop/uniffi.def diff --git a/apollo/build.gradle.kts b/apollo/build.gradle.kts index 31a836505..51221c877 100644 --- a/apollo/build.gradle.kts +++ b/apollo/build.gradle.kts @@ -21,6 +21,24 @@ plugins { id("dev.petuska.npm.publish") version "3.4.1" } +val ed25519bip32Dir = file("../../rust-ed25519-bip32/wrapper") +val uniffiBindings = ed25519bip32Dir.resolve("out/kmpp-uniffi") +val jniLibs = uniffiBindings.resolve("jniLibs") +val processBinaries = tasks.register("processBinaries", Copy::class) { + val directory = buildDir + .resolve("processedResources") + .resolve("jvm") + .resolve("main") + + from(uniffiBindings.resolve("macos-native").resolve("dynamic")) + include("*.dylib") + into(directory) +} + +tasks.withType { + dependsOn(processBinaries) +} + /** * Adds a Swift interop configuration for a library. * @@ -81,6 +99,28 @@ val javadocJar by tasks.registering(Jar::class) { } kotlin { + fun addLibs(libDirectory: String, target: KotlinNativeTarget) { + target.compilations.getByName("main") { + val uniffi by cinterops.creating { + val headerDir = uniffiBindings.resolve("nativeInterop/cinterop/headers/ed25519_bip32") + this.includeDirs(headerDir) + packageName("ed25519_bip32.cinterop") + extraOpts("-libraryPath", libDirectory) + } + } + + target.binaries.all { + linkerOpts("-L${libDirectory}", "-led25519_bip32") + linkerOpts("-Wl,-framework,Security") + } + + target.binaries{ + sharedLib{ + baseName = "ed25519_bip32" + } + } + } + androidTarget { publishAllLibraryVariants() } @@ -103,6 +143,9 @@ kotlin { } } iosArm64 { + val libDirectory = "${ed25519bip32Dir}/target/aarch64-apple-ios/release" + addLibs(libDirectory, this) + swiftCinterop("IOHKSecureRandomGeneration", name) swiftCinterop("IOHKCryptoKit", name) @@ -122,10 +165,12 @@ kotlin { binaries.framework { baseName = "ApolloLibrary" embedBitcode(BitcodeEmbeddingMode.DISABLE) - freeCompilerArgs += listOf("-Xoverride-konan-properties=minVersion.ios=13.0;minVersionSinceXcode15.ios=13.0") } } iosX64 { + val libDirectory = "${ed25519bip32Dir}/target/x86_64-apple-ios/release" + addLibs(libDirectory, this) + swiftCinterop("IOHKSecureRandomGeneration", name) swiftCinterop("IOHKCryptoKit", name) @@ -145,7 +190,6 @@ kotlin { binaries.framework { baseName = "ApolloLibrary" embedBitcode(BitcodeEmbeddingMode.DISABLE) - freeCompilerArgs += listOf("-Xoverride-konan-properties=minVersion.ios=13.0;minVersionSinceXcode15.ios=13.0") if (os.isMacOsX) { if (System.getenv().containsKey("XCODE_VERSION_MAJOR") && System.getenv("XCODE_VERSION_MAJOR") == "1500") { linkerOpts += "-ld64" @@ -154,6 +198,9 @@ kotlin { } } iosSimulatorArm64 { + val libDirectory = "${ed25519bip32Dir}/target/aarch64-apple-ios-sim/release" + addLibs(libDirectory, this) + swiftCinterop("IOHKSecureRandomGeneration", name) swiftCinterop("IOHKCryptoKit", name) @@ -173,10 +220,12 @@ kotlin { binaries.framework { baseName = "ApolloLibrary" embedBitcode(BitcodeEmbeddingMode.DISABLE) - freeCompilerArgs += listOf("-Xoverride-konan-properties=minVersion.ios_simulator_arm64=13.0;minVersionSinceXcode15.ios=13.0") } } macosArm64 { + val libDirectory = "${uniffiBindings}/macos-native/static" + addLibs(libDirectory, this) + swiftCinterop("IOHKSecureRandomGeneration", name) swiftCinterop("IOHKCryptoKit", name) @@ -196,7 +245,6 @@ kotlin { binaries.framework { baseName = "ApolloLibrary" embedBitcode(BitcodeEmbeddingMode.DISABLE) - freeCompilerArgs += listOf("-Xoverride-konan-properties=minVersion.macos=11.0;minVersionSinceXcode15.macos=11.0") } } js(IR) { @@ -243,11 +291,22 @@ kotlin { sourceSets { val commonMain by getting { + val commonDir = uniffiBindings.resolve("commonMain").resolve("kotlin") + val file = commonDir.resolve("ed25519_bip32").resolve("ed25519_bip32.common.kt") + val find = Regex("\\t|(?:\\s{4})class ([a-zA-Z]{2,50})\\(\\n.{0,50}\\n.{0,20}: ErrorCode\\(\\) \\{(?:.|\\n){0,100}?(?:\\t|(?:\\s{4}))\\}") + val contents = file.readText().replace(find){ + "class ${it.groupValues[1]}(override val message: kotlin.String): ErrorCode()" + } + file.writeText(contents) + kotlin.srcDir(commonDir) + dependencies { implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.2") implementation("com.ionspin.kotlin:bignum:0.3.9") implementation("org.kotlincrypto.macs:hmac-sha2:0.3.0") implementation("org.kotlincrypto.hash:sha2:0.4.0") + + implementation("com.ionspin.kotlin:multiplatform-crypto-libsodium-bindings:0.9.0") } } val commonTest by getting { @@ -256,11 +315,13 @@ kotlin { } } val androidMain by getting { + kotlin.srcDir(uniffiBindings.resolve("jvmMain").resolve("kotlin")) + dependencies { api("fr.acinq.secp256k1:secp256k1-kmp:0.14.0") implementation("fr.acinq.secp256k1:secp256k1-kmp-jni-jvm:0.11.0") implementation("fr.acinq.secp256k1:secp256k1-kmp-jni-android:0.14.0") - implementation("com.google.guava:guava:30.1-jre") + implementation("com.godogle.guava:guava:30.1-jre") implementation("org.bouncycastle:bcprov-jdk15on:1.68") implementation("org.bitcoinj:bitcoinj-core:0.16.2") } @@ -271,12 +332,15 @@ kotlin { } } val jvmMain by getting { + kotlin.srcDir(uniffiBindings.resolve("jvmMain").resolve("kotlin")) + dependencies { api("fr.acinq.secp256k1:secp256k1-kmp:0.14.0") implementation("fr.acinq.secp256k1:secp256k1-kmp-jni-jvm:0.11.0") implementation("com.google.guava:guava:30.1-jre") implementation("org.bouncycastle:bcprov-jdk15on:1.68") implementation("org.bitcoinj:bitcoinj-core:0.16.2") + } } val jvmTest by getting { @@ -315,6 +379,11 @@ kotlin { .resolve("kotlin") ) } + + all { +// languageSettings.optIn("kotlin.RequiresOptIn") +// languageSettings.optIn("kotlinx.cinterop.ExperimentalForeignApi") + } } // Enable the export of KDoc (Experimental feature) to Generated Native targets (Apple, Linux, etc.) @@ -338,6 +407,8 @@ android { namespace = "io.iohk.atala.prism.apollo" compileSdk = 34 sourceSets["main"].manifest.srcFile("src/androidMain/AndroidManifest.xml") + sourceSets["main"].jniLibs.srcDir(jniLibs) + defaultConfig { minSdk = 21 } @@ -516,4 +587,4 @@ afterEvaluate { this.enabled = false } } -} +} \ No newline at end of file diff --git a/apollo/src/nativeInterop/cinterop/uniffi.def b/apollo/src/nativeInterop/cinterop/uniffi.def new file mode 100644 index 000000000..7f7127c4d --- /dev/null +++ b/apollo/src/nativeInterop/cinterop/uniffi.def @@ -0,0 +1,13 @@ +package = ed25519_bip32.cinterop +headers = ed25519_bip32.h +headerFilter = ** + +staticLibraries.ios = libed25519_bip32_wrapper.a + + +libraryPaths.ios_x64 = ../../rust-ed25519-bip32/wrapper/target/x86_64-apple-ios/release +libraryPaths.ios_arm64 = ../../rust-ed25519-bip32/wrapper/target/aarch64-apple-ios/release +libraryPaths.ios_simulator_arm64 = ../../rust-ed25519-bip32/wrapper/target/aarch64-apple-ios-sim/release + +staticLibraries.osx = libed25519_bip32_wrapper.a +libraryPaths.osx = ../../rust-ed25519-bip32/wrapper/out/kmpp-uniffi/macos-native/static \ No newline at end of file From 4eb0600cc73558baafe22b47c98648e86f57c3fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Francisco=20Javier=20Ribo=CC=81=20Labrador?= Date: Tue, 16 Apr 2024 17:43:48 +0200 Subject: [PATCH 02/39] =?UTF-8?q?fix:=20EdHDKey=20build=20for=20kmm=20Sign?= =?UTF-8?q?ed-off-by:=20Francisco=20Javier=20Rib=C3=B3=20Labrador=20?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apollo/build.gradle.kts | 55 ++++++++--- .../atala/prism/apollo/derivation/EdHDKey.kt | 98 +++++++++++++++++++ 2 files changed, 139 insertions(+), 14 deletions(-) create mode 100644 apollo/src/allButJSMain/kotlin/io/iohk/atala/prism/apollo/derivation/EdHDKey.kt diff --git a/apollo/build.gradle.kts b/apollo/build.gradle.kts index 51221c877..46701b60b 100644 --- a/apollo/build.gradle.kts +++ b/apollo/build.gradle.kts @@ -35,6 +35,8 @@ val processBinaries = tasks.register("processBinaries", Copy::class) { into(directory) } + + tasks.withType { dependsOn(processBinaries) } @@ -98,8 +100,13 @@ val javadocJar by tasks.registering(Jar::class) { from(tasks.dokkaHtml) } + + kotlin { + + fun addLibs(libDirectory: String, target: KotlinNativeTarget) { + target.compilations.getByName("main") { val uniffi by cinterops.creating { val headerDir = uniffiBindings.resolve("nativeInterop/cinterop/headers/ed25519_bip32") @@ -291,21 +298,14 @@ kotlin { sourceSets { val commonMain by getting { - val commonDir = uniffiBindings.resolve("commonMain").resolve("kotlin") - val file = commonDir.resolve("ed25519_bip32").resolve("ed25519_bip32.common.kt") - val find = Regex("\\t|(?:\\s{4})class ([a-zA-Z]{2,50})\\(\\n.{0,50}\\n.{0,20}: ErrorCode\\(\\) \\{(?:.|\\n){0,100}?(?:\\t|(?:\\s{4}))\\}") - val contents = file.readText().replace(find){ - "class ${it.groupValues[1]}(override val message: kotlin.String): ErrorCode()" - } - file.writeText(contents) - kotlin.srcDir(commonDir) - dependencies { + implementation("org.jetbrains.kotlinx:atomicfu:0.22.0") + implementation("net.java.dev.jna:jna:5.13.0") + implementation("com.squareup.okio:okio:3.2.0") implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.2") implementation("com.ionspin.kotlin:bignum:0.3.9") implementation("org.kotlincrypto.macs:hmac-sha2:0.3.0") implementation("org.kotlincrypto.hash:sha2:0.4.0") - implementation("com.ionspin.kotlin:multiplatform-crypto-libsodium-bindings:0.9.0") } } @@ -314,24 +314,44 @@ kotlin { implementation(kotlin("test")) } } + + val allButJSMain by creating { + this.dependsOn(commonMain) + val commonDir = uniffiBindings.resolve("commonMain").resolve("kotlin") + val file = commonDir.resolve("ed25519_bip32").resolve("ed25519_bip32.common.kt") + val find = Regex("\\t|(?:\\s{4})class ([a-zA-Z]{2,50})\\(\\n.{0,50}\\n.{0,20}: ErrorCode\\(\\) \\{(?:.|\\n){0,100}?(?:\\t|(?:\\s{4}))\\}") + val contents = file.readText().replace(find){ + "class ${it.groupValues[1]}(override val message: kotlin.String): ErrorCode()" + } + file.writeText(contents) + kotlin.srcDir(commonDir) + } + val allButJSTest by creating { + this.dependsOn(commonTest) + } + + + val androidMain by getting { kotlin.srcDir(uniffiBindings.resolve("jvmMain").resolve("kotlin")) - + this.dependsOn(allButJSMain) dependencies { api("fr.acinq.secp256k1:secp256k1-kmp:0.14.0") implementation("fr.acinq.secp256k1:secp256k1-kmp-jni-jvm:0.11.0") implementation("fr.acinq.secp256k1:secp256k1-kmp-jni-android:0.14.0") - implementation("com.godogle.guava:guava:30.1-jre") + implementation("com.google.guava:guava:30.1-jre") implementation("org.bouncycastle:bcprov-jdk15on:1.68") implementation("org.bitcoinj:bitcoinj-core:0.16.2") } } val androidUnitTest by getting { + this.dependsOn(allButJSTest) dependencies { implementation("junit:junit:4.13.2") } } val jvmMain by getting { + this.dependsOn(allButJSMain) kotlin.srcDir(uniffiBindings.resolve("jvmMain").resolve("kotlin")) dependencies { @@ -344,6 +364,8 @@ kotlin { } } val jvmTest by getting { + this.dependsOn(allButJSTest) + dependencies { implementation("junit:junit:4.13.2") } @@ -368,6 +390,8 @@ kotlin { val jsTest by getting val appleMain by getting { + this.dependsOn(allButJSMain) + kotlin.srcDirs( secp256k1Dir .resolve("src") @@ -375,14 +399,17 @@ kotlin { .resolve("kotlin"), secp256k1Dir .resolve("src") + .resolve("nativeMain") + .resolve("kotlin"), + uniffiBindings .resolve("nativeMain") .resolve("kotlin") ) } all { -// languageSettings.optIn("kotlin.RequiresOptIn") -// languageSettings.optIn("kotlinx.cinterop.ExperimentalForeignApi") + languageSettings.optIn("kotlin.RequiresOptIn") + languageSettings.optIn("kotlinx.cinterop.ExperimentalForeignApi") } } diff --git a/apollo/src/allButJSMain/kotlin/io/iohk/atala/prism/apollo/derivation/EdHDKey.kt b/apollo/src/allButJSMain/kotlin/io/iohk/atala/prism/apollo/derivation/EdHDKey.kt new file mode 100644 index 000000000..fb7ddf52f --- /dev/null +++ b/apollo/src/allButJSMain/kotlin/io/iohk/atala/prism/apollo/derivation/EdHDKey.kt @@ -0,0 +1,98 @@ +package io.iohk.atala.prism.apollo.derivation + +import com.ionspin.kotlin.bignum.integer.BigInteger +import com.ionspin.kotlin.bignum.integer.toBigInteger +import ed25519_bip32.XPrvWrapper +import io.iohk.atala.prism.apollo.utils.ECConfig +import kotlin.js.ExperimentalJsExport +import kotlin.js.JsExport +import kotlin.js.JsName + + +/** + * Represents and HDKey with its derive methods + */ +@OptIn(ExperimentalJsExport::class) +@JsExport +class EdHDKey( + val privateKey: ByteArray, + val chainCode: ByteArray, + val publicKey: ByteArray? = null, + val depth: Int = 0, + val index: BigIntegerWrapper = BigIntegerWrapper(0) +) { + /** + * Constructs a new EdHDKey object from a seed, depth, and child index. + * + * @param seed The seed used to derive the private key and chain code. + * @param depth The depth of the HDKey. + * @param childIndex The child index of the HDKey. + * + * @throws IllegalArgumentException if the seed length is not equal to 64. + */ + + fun initFromSeed(seed: ByteArray): EdHDKey { + require(seed.size == 64) { + "Seed expected byte length to be ${ECConfig.PRIVATE_KEY_BYTE_SIZE}" + } + + val key = seed.sliceArray(0 until 32) + val chainCode = seed.sliceArray(32 until seed.size) + val wrapper = XPrvWrapper.fromNonextendedNoforce(key, chainCode) + + return EdHDKey( + privateKey = wrapper.extendedSecretKey(), + chainCode = wrapper.chainCode(), + ) + } + + /** + * Method to derive an HDKey by a path + * + * @param path value used to derive a key + */ + fun derive(path: String): EdHDKey { + if (!path.matches(Regex("^[mM].*"))) { + throw Error("Path must start with \"m\" or \"M\"") + } + if (Regex("^[mM]'?$").matches(path)) { + return this + } + val parts = path.replace(Regex("^[mM]'?/"), "").split("/") + var child = this + + for (c in parts) { + val m = Regex("^(\\d+)('?)$").find(c)?.groupValues + if (m == null || m.size != 3) { + throw Error("Invalid child index: $c") + } + val idx = m[1].toBigInteger() + if (idx >= HDKey.HARDENED_OFFSET) { + throw Error("Invalid index") + } + val finalIdx = if (m[2] == "'") idx + HDKey.HARDENED_OFFSET else idx + + child = child.deriveChild(BigIntegerWrapper(finalIdx)) + } + + return child + } + + /** + * Method to derive an HDKey child by index + * + * @param index value used to derive a key + */ + fun deriveChild(wrappedIndex: BigIntegerWrapper): EdHDKey { + val extendedKey = privateKey.plus(chainCode) + val wrapper = XPrvWrapper.fromBytes(extendedKey) + val derived = wrapper.derive(wrappedIndex.value.uintValue()) + + return EdHDKey( + privateKey = derived.extendedSecretKey(), + chainCode = derived.chainCode(), + depth = depth + 1, + index = wrappedIndex + ) + } +} \ No newline at end of file From de2a13b73cbc1b817d0ae8908111b48b13016e77 Mon Sep 17 00:00:00 2001 From: Curtish Date: Thu, 18 Apr 2024 15:11:50 +0100 Subject: [PATCH 03/39] js EdHDKey + external --- .../atala/prism/apollo/derivation/EdHDKey.kt | 12 +-- .../atala/prism/apollo/derivation/EdHDKey.kt | 88 +++++++++++++++++++ .../apollo/utils/external/Ed25519_Bip32.kt | 22 +++++ 3 files changed, 111 insertions(+), 11 deletions(-) create mode 100644 apollo/src/jsMain/kotlin/io/iohk/atala/prism/apollo/derivation/EdHDKey.kt create mode 100644 apollo/src/jsMain/kotlin/io/iohk/atala/prism/apollo/utils/external/Ed25519_Bip32.kt diff --git a/apollo/src/allButJSMain/kotlin/io/iohk/atala/prism/apollo/derivation/EdHDKey.kt b/apollo/src/allButJSMain/kotlin/io/iohk/atala/prism/apollo/derivation/EdHDKey.kt index fb7ddf52f..115bddab4 100644 --- a/apollo/src/allButJSMain/kotlin/io/iohk/atala/prism/apollo/derivation/EdHDKey.kt +++ b/apollo/src/allButJSMain/kotlin/io/iohk/atala/prism/apollo/derivation/EdHDKey.kt @@ -1,19 +1,13 @@ package io.iohk.atala.prism.apollo.derivation -import com.ionspin.kotlin.bignum.integer.BigInteger import com.ionspin.kotlin.bignum.integer.toBigInteger import ed25519_bip32.XPrvWrapper import io.iohk.atala.prism.apollo.utils.ECConfig -import kotlin.js.ExperimentalJsExport -import kotlin.js.JsExport -import kotlin.js.JsName /** * Represents and HDKey with its derive methods */ -@OptIn(ExperimentalJsExport::class) -@JsExport class EdHDKey( val privateKey: ByteArray, val chainCode: ByteArray, @@ -22,15 +16,11 @@ class EdHDKey( val index: BigIntegerWrapper = BigIntegerWrapper(0) ) { /** - * Constructs a new EdHDKey object from a seed, depth, and child index. + * Constructs a new EdHDKey object from a seed * * @param seed The seed used to derive the private key and chain code. - * @param depth The depth of the HDKey. - * @param childIndex The child index of the HDKey. - * * @throws IllegalArgumentException if the seed length is not equal to 64. */ - fun initFromSeed(seed: ByteArray): EdHDKey { require(seed.size == 64) { "Seed expected byte length to be ${ECConfig.PRIVATE_KEY_BYTE_SIZE}" diff --git a/apollo/src/jsMain/kotlin/io/iohk/atala/prism/apollo/derivation/EdHDKey.kt b/apollo/src/jsMain/kotlin/io/iohk/atala/prism/apollo/derivation/EdHDKey.kt new file mode 100644 index 000000000..b65ba08af --- /dev/null +++ b/apollo/src/jsMain/kotlin/io/iohk/atala/prism/apollo/derivation/EdHDKey.kt @@ -0,0 +1,88 @@ +package io.iohk.atala.prism.apollo.derivation + +import com.ionspin.kotlin.bignum.integer.toBigInteger +import io.iohk.atala.prism.apollo.utils.ECConfig +import io.iohk.atala.prism.apollo.utils.external.ed25519_bip32 + +/** + * Represents and HDKey with its derive methods + */ +@OptIn(ExperimentalJsExport::class) +@JsExport +class EdHDKey( + val privateKey: ByteArray, + val chainCode: ByteArray, + val publicKey: ByteArray? = null, + val depth: Int = 0, + val index: BigIntegerWrapper = BigIntegerWrapper(0) +) { + /** + * Constructs a new EdHDKey object from a seed + * + * @param seed The seed used to derive the private key and chain code. + * @throws IllegalArgumentException if the seed length is not equal to 64. + */ + fun initFromSeed(seed: ByteArray): EdHDKey { + require(seed.size == 64) { + "Seed expected byte length to be ${ECConfig.PRIVATE_KEY_BYTE_SIZE}" + } + + val key = seed.sliceArray(0 until 32) + val chainCode = seed.sliceArray(32 until seed.size) + val wrapper = ed25519_bip32.XPrvWrapper.from_nonextended_noforce(key, chainCode) + + return EdHDKey( + privateKey = wrapper.extended_secret_key(), + chainCode = wrapper.chain_code(), + ) + } + + /** + * Method to derive an HDKey by a path + * + * @param path value used to derive a key + */ + fun derive(path: String): EdHDKey { + if (!path.matches(Regex("^[mM].*"))) { + throw Error("Path must start with \"m\" or \"M\"") + } + if (Regex("^[mM]'?$").matches(path)) { + return this + } + val parts = path.replace(Regex("^[mM]'?/"), "").split("/") + var child = this + + for (c in parts) { + val m = Regex("^(\\d+)('?)$").find(c)?.groupValues + if (m == null || m.size != 3) { + throw Error("Invalid child index: $c") + } + val idx = m[1].toBigInteger() + if (idx >= HDKey.HARDENED_OFFSET) { + throw Error("Invalid index") + } + val finalIdx = if (m[2] == "'") idx + HDKey.HARDENED_OFFSET else idx + + child = child.deriveChild(BigIntegerWrapper(finalIdx)) + } + + return child + } + + /** + * Method to derive an HDKey child by index + * + * @param index value used to derive a key + */ + fun deriveChild(wrappedIndex: BigIntegerWrapper): EdHDKey { + val wrapper = ed25519_bip32.XPrvWrapper.from_extended_and_chaincode(privateKey, chainCode) + val derived = wrapper.derive(wrappedIndex.value.uintValue()) + + return EdHDKey( + privateKey = derived.extended_secret_key(), + chainCode = derived.chain_code(), + depth = depth + 1, + index = wrappedIndex + ) + } +} \ No newline at end of file diff --git a/apollo/src/jsMain/kotlin/io/iohk/atala/prism/apollo/utils/external/Ed25519_Bip32.kt b/apollo/src/jsMain/kotlin/io/iohk/atala/prism/apollo/utils/external/Ed25519_Bip32.kt new file mode 100644 index 000000000..ff416bdb3 --- /dev/null +++ b/apollo/src/jsMain/kotlin/io/iohk/atala/prism/apollo/utils/external/Ed25519_Bip32.kt @@ -0,0 +1,22 @@ +package io.iohk.atala.prism.apollo.utils.external + +external interface XPrvWrapper { + fun public(): ByteArray + + fun derive(index: Any): XPrvWrapper + + fun extended_secret_key(): ByteArray + + fun chain_code(): ByteArray + + var from_nonextended_noforce: (js_bytes: ByteArray, js_chain_code: ByteArray) -> XPrvWrapper + + var from_extended_and_chaincode: (js_bytes: ByteArray, js_chain_code: ByteArray) -> XPrvWrapper +} + +external interface ed25519_bip32_export { + var XPrvWrapper: XPrvWrapper +} + +@JsModule("ed25519_bip32_export") +external val ed25519_bip32: ed25519_bip32_export From fe6e2a98402e620084ecce3bd70940b01c85d912 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Francisco=20Javier=20Ribo=CC=81=20Labrador?= Date: Thu, 18 Apr 2024 18:30:18 +0200 Subject: [PATCH 04/39] fix: import the bip32 package from js --- apollo/build.gradle.kts | 9 +++++---- .../atala/prism/apollo/utils/external/Ed25519_Bip32.kt | 3 ++- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/apollo/build.gradle.kts b/apollo/build.gradle.kts index 46701b60b..77fd3c8a0 100644 --- a/apollo/build.gradle.kts +++ b/apollo/build.gradle.kts @@ -255,6 +255,11 @@ kotlin { } } js(IR) { + val externalDir = File(projectDir, "../build/js/packages/Apollo/kotlin") // Destination directory within your project + val sourceDir = File(projectDir,"../../rust-ed25519-bip32/wasm/pkg") // Source directory + + // Copy files from sourceDir to externalDir + sourceDir.copyRecursively(externalDir, overwrite = true) this.moduleName = currentModuleName this.binaries.library() this.useCommonJs() @@ -299,14 +304,10 @@ kotlin { sourceSets { val commonMain by getting { dependencies { - implementation("org.jetbrains.kotlinx:atomicfu:0.22.0") - implementation("net.java.dev.jna:jna:5.13.0") - implementation("com.squareup.okio:okio:3.2.0") implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.2") implementation("com.ionspin.kotlin:bignum:0.3.9") implementation("org.kotlincrypto.macs:hmac-sha2:0.3.0") implementation("org.kotlincrypto.hash:sha2:0.4.0") - implementation("com.ionspin.kotlin:multiplatform-crypto-libsodium-bindings:0.9.0") } } val commonTest by getting { diff --git a/apollo/src/jsMain/kotlin/io/iohk/atala/prism/apollo/utils/external/Ed25519_Bip32.kt b/apollo/src/jsMain/kotlin/io/iohk/atala/prism/apollo/utils/external/Ed25519_Bip32.kt index ff416bdb3..499c1b6f4 100644 --- a/apollo/src/jsMain/kotlin/io/iohk/atala/prism/apollo/utils/external/Ed25519_Bip32.kt +++ b/apollo/src/jsMain/kotlin/io/iohk/atala/prism/apollo/utils/external/Ed25519_Bip32.kt @@ -18,5 +18,6 @@ external interface ed25519_bip32_export { var XPrvWrapper: XPrvWrapper } -@JsModule("ed25519_bip32_export") +@JsModule("./ed25519_bip32_wasm.mjs") +@JsNonModule external val ed25519_bip32: ed25519_bip32_export From 21fb5a50ccf425f336559d04ef409554f9fe04b2 Mon Sep 17 00:00:00 2001 From: Curtish Date: Tue, 23 Apr 2024 17:26:31 +0100 Subject: [PATCH 05/39] including rust-ed25519-bip32 submodule --- .gitmodules | 5 + apollo/build.gradle.kts | 222 ++++++++++++------ .../atala/prism/apollo/derivation/EdHDKey.kt | 8 +- .../atala/prism/apollo/derivation/EdHDKey.kt | 4 +- .../apollo/utils/external/Ed25519_Bip32.kt | 2 +- rust-ed25519-bip32 | 1 + 6 files changed, 157 insertions(+), 85 deletions(-) create mode 160000 rust-ed25519-bip32 diff --git a/.gitmodules b/.gitmodules index db8b83818..16bf8d3ee 100644 --- a/.gitmodules +++ b/.gitmodules @@ -2,3 +2,8 @@ path = secp256k1-kmp/native/secp256k1 url = https://github.com/bitcoin-core/secp256k1 branch = master + +[submodule "rust-ed25519-bip32"] + path = rust-ed25519-bip32 + url = https://github.com/input-output-hk/rust-ed25519-bip32.git + branch = rust-uniffi diff --git a/apollo/build.gradle.kts b/apollo/build.gradle.kts index 77fd3c8a0..17e130fba 100644 --- a/apollo/build.gradle.kts +++ b/apollo/build.gradle.kts @@ -12,6 +12,7 @@ import java.time.Year val currentModuleName: String = "Apollo" val os: OperatingSystem = OperatingSystem.current() val secp256k1Dir = rootDir.resolve("secp256k1-kmp") +val ed25519bip32Dir = rootDir.resolve("rust-ed25519-bip32") plugins { kotlin("multiplatform") @@ -21,26 +22,6 @@ plugins { id("dev.petuska.npm.publish") version "3.4.1" } -val ed25519bip32Dir = file("../../rust-ed25519-bip32/wrapper") -val uniffiBindings = ed25519bip32Dir.resolve("out/kmpp-uniffi") -val jniLibs = uniffiBindings.resolve("jniLibs") -val processBinaries = tasks.register("processBinaries", Copy::class) { - val directory = buildDir - .resolve("processedResources") - .resolve("jvm") - .resolve("main") - - from(uniffiBindings.resolve("macos-native").resolve("dynamic")) - include("*.dylib") - into(directory) -} - - - -tasks.withType { - dependsOn(processBinaries) -} - /** * Adds a Swift interop configuration for a library. * @@ -100,34 +81,122 @@ val javadocJar by tasks.registering(Jar::class) { from(tasks.dokkaHtml) } +fun createCopyTask( + name: String, + fromDir: File, + intoDir: File +) = tasks.register(name) { + group = "build-Ed25519-Bip32" + duplicatesStrategy = DuplicatesStrategy.INCLUDE + include("*.so", "*.a", "*.d", "*.dylib", "**/*.kt", "*.js") + from(fromDir) + into(intoDir) +} +val sourceDir = ed25519bip32Dir.resolve("wrapper").resolve("target") +val buildDir = projectDir.resolve("build").resolve("generatedResources") +val generatedDir = projectDir.resolve("build").resolve("generated") + +val copyEd25519Bip32GeneratedTask = createCopyTask( + "copyEd25519Bip32Generated", + ed25519bip32Dir.resolve("wrapper").resolve("build").resolve("generated"), + generatedDir +) + +val copyEd25519Bip32ForMacOSX8664Task = createCopyTask( + "copyEd25519Bip32ForMacOSX86_64", + sourceDir.resolve("x86_64-apple-darwin").resolve("release"), + buildDir.resolve("jvm").resolve("main").resolve("darwin-x86-64") +) + +val copyEd25519Bip32ForMacOSArch64Task = createCopyTask( + "copyEd25519Bip32ForMacOSArch64", + sourceDir.resolve("aarch64-apple-darwin").resolve("release"), + buildDir.resolve("jvm").resolve("main").resolve("darwin-aarch64") +) + +val copyEd25519Bip32ForLinuxX8664Task = createCopyTask( + "copyEd25519Bip32ForLinuxX86_64", + sourceDir.resolve("x86_64-unknown-linux-gnu").resolve("release"), + buildDir.resolve("jvm").resolve("main").resolve("linux-x86-64") +) + +val copyEd25519Bip32ForLinuxArch64Task = createCopyTask( + "copyEd25519Bip32ForLinuxArch64", + sourceDir.resolve("aarch64-unknown-linux-gnu").resolve("release"), + buildDir.resolve("jvm").resolve("main").resolve("linux-aarch64") +) + +val copyEd25519Bip32ForAndroidX8664Task = createCopyTask( + "copyEd25519Bip32ForAndroidX86_64", + sourceDir.resolve("x86_64-linux-android").resolve("release"), + buildDir.resolve("android").resolve("main").resolve("jniLibs").resolve("x86_64") +) + +val copyEd25519Bip32ForAndroidArch64Task = createCopyTask( + "copyEd25519Bip32ForAndroidArch64", + sourceDir.resolve("aarch64-linux-android").resolve("release"), + buildDir.resolve("android").resolve("main").resolve("jniLibs").resolve("arm64-v8a") +) + +val copyEd25519Bip32ForAndroidI686Task = createCopyTask( + "copyEd25519Bip32ForAndroidI686", + sourceDir.resolve("i686-linux-android").resolve("release"), + buildDir.resolve("android").resolve("main").resolve("jniLibs").resolve("x86") +) + +val copyEd25519Bip32ForAndroidArmv7aTask = createCopyTask( + "copyEd25519Bip32ForAndroidArmv7a", + sourceDir.resolve("armv7-linux-androideabi").resolve("release"), + buildDir.resolve("android").resolve("main").resolve("jniLibs").resolve("armeabi-v7a") +) + +val copyEd25519Bip32Wrapper by tasks.register("copyEd25519Bip32") { + dependsOn( + copyEd25519Bip32GeneratedTask, + copyEd25519Bip32ForMacOSX8664Task, + copyEd25519Bip32ForMacOSArch64Task, + copyEd25519Bip32ForLinuxX8664Task, + copyEd25519Bip32ForLinuxArch64Task, + copyEd25519Bip32ForAndroidX8664Task, + copyEd25519Bip32ForAndroidArch64Task, + copyEd25519Bip32ForAndroidI686Task, + copyEd25519Bip32ForAndroidArmv7aTask + ) + mustRunAfter(buildEd25519Bip32Wrapper) +} -kotlin { - +val buildEd25519Bip32Wrapper by tasks.register("buildEd25519Bip32Wrapper") { + group = "build-Ed25519-Bip32" + workingDir = ed25519bip32Dir.resolve("wrapper") + commandLine("./build-kotlin-library.sh") +} - fun addLibs(libDirectory: String, target: KotlinNativeTarget) { +val copyEd25519Bip32Wasm = createCopyTask( + "copyEd25519Bip32GeneratedWasm", + ed25519bip32Dir.resolve("wasm").resolve("build"), + projectDir.resolve("build").resolve("js").resolve("packages").resolve("Apollo").resolve("kotlin") +) +copyEd25519Bip32Wasm.configure { + mustRunAfter(buildEd25519Bip32Wasm) +} - target.compilations.getByName("main") { - val uniffi by cinterops.creating { - val headerDir = uniffiBindings.resolve("nativeInterop/cinterop/headers/ed25519_bip32") - this.includeDirs(headerDir) - packageName("ed25519_bip32.cinterop") - extraOpts("-libraryPath", libDirectory) - } - } +val buildEd25519Bip32Wasm by tasks.register("buildEd25519Bip32Wasm") { + group = "build-Ed25519-Bip32" + workingDir = ed25519bip32Dir.resolve("wasm") + commandLine("./build_kotlin_library.sh") +} - target.binaries.all { - linkerOpts("-L${libDirectory}", "-led25519_bip32") - linkerOpts("-Wl,-framework,Security") - } +val buildEd25519Bip32Task by tasks.register("buildEd25519Bip32") { + group = "build-Ed25519-Bip32" + dependsOn(buildEd25519Bip32Wasm, copyEd25519Bip32Wasm, buildEd25519Bip32Wrapper, copyEd25519Bip32Wrapper) +} - target.binaries{ - sharedLib{ - baseName = "ed25519_bip32" - } - } - } +tasks.withType { + dependsOn(buildEd25519Bip32Task) +} +kotlin { androidTarget { publishAllLibraryVariants() } @@ -150,9 +219,6 @@ kotlin { } } iosArm64 { - val libDirectory = "${ed25519bip32Dir}/target/aarch64-apple-ios/release" - addLibs(libDirectory, this) - swiftCinterop("IOHKSecureRandomGeneration", name) swiftCinterop("IOHKCryptoKit", name) @@ -175,12 +241,8 @@ kotlin { } } iosX64 { - val libDirectory = "${ed25519bip32Dir}/target/x86_64-apple-ios/release" - addLibs(libDirectory, this) - swiftCinterop("IOHKSecureRandomGeneration", name) swiftCinterop("IOHKCryptoKit", name) - secp256k1CInterop("ios") // https://youtrack.jetbrains.com/issue/KT-39396 compilations["main"].kotlinOptions.freeCompilerArgs += listOf( @@ -205,9 +267,6 @@ kotlin { } } iosSimulatorArm64 { - val libDirectory = "${ed25519bip32Dir}/target/aarch64-apple-ios-sim/release" - addLibs(libDirectory, this) - swiftCinterop("IOHKSecureRandomGeneration", name) swiftCinterop("IOHKCryptoKit", name) @@ -230,9 +289,6 @@ kotlin { } } macosArm64 { - val libDirectory = "${uniffiBindings}/macos-native/static" - addLibs(libDirectory, this) - swiftCinterop("IOHKSecureRandomGeneration", name) swiftCinterop("IOHKCryptoKit", name) @@ -255,11 +311,6 @@ kotlin { } } js(IR) { - val externalDir = File(projectDir, "../build/js/packages/Apollo/kotlin") // Destination directory within your project - val sourceDir = File(projectDir,"../../rust-ed25519-bip32/wasm/pkg") // Source directory - - // Copy files from sourceDir to externalDir - sourceDir.copyRecursively(externalDir, overwrite = true) this.moduleName = currentModuleName this.binaries.library() this.useCommonJs() @@ -308,6 +359,8 @@ kotlin { implementation("com.ionspin.kotlin:bignum:0.3.9") implementation("org.kotlincrypto.macs:hmac-sha2:0.3.0") implementation("org.kotlincrypto.hash:sha2:0.4.0") + implementation("com.squareup.okio:okio:3.2.0") + implementation("org.jetbrains.kotlinx:atomicfu:0.22.0") } } val commonTest by getting { @@ -318,24 +371,16 @@ kotlin { val allButJSMain by creating { this.dependsOn(commonMain) - val commonDir = uniffiBindings.resolve("commonMain").resolve("kotlin") - val file = commonDir.resolve("ed25519_bip32").resolve("ed25519_bip32.common.kt") - val find = Regex("\\t|(?:\\s{4})class ([a-zA-Z]{2,50})\\(\\n.{0,50}\\n.{0,20}: ErrorCode\\(\\) \\{(?:.|\\n){0,100}?(?:\\t|(?:\\s{4}))\\}") - val contents = file.readText().replace(find){ - "class ${it.groupValues[1]}(override val message: kotlin.String): ErrorCode()" - } - file.writeText(contents) - kotlin.srcDir(commonDir) + kotlin.srcDir(generatedDir.resolve("commonMain").resolve("kotlin")) } val allButJSTest by creating { this.dependsOn(commonTest) } - - val androidMain by getting { - kotlin.srcDir(uniffiBindings.resolve("jvmMain").resolve("kotlin")) this.dependsOn(allButJSMain) + kotlin.srcDir(generatedDir.resolve("jvmMain").resolve("kotlin")) + dependencies { api("fr.acinq.secp256k1:secp256k1-kmp:0.14.0") implementation("fr.acinq.secp256k1:secp256k1-kmp-jni-jvm:0.11.0") @@ -343,6 +388,7 @@ kotlin { implementation("com.google.guava:guava:30.1-jre") implementation("org.bouncycastle:bcprov-jdk15on:1.68") implementation("org.bitcoinj:bitcoinj-core:0.16.2") + implementation("net.java.dev.jna:jna:5.13.0@aar") } } val androidUnitTest by getting { @@ -353,7 +399,7 @@ kotlin { } val jvmMain by getting { this.dependsOn(allButJSMain) - kotlin.srcDir(uniffiBindings.resolve("jvmMain").resolve("kotlin")) + kotlin.srcDir(generatedDir.resolve("jvmMain").resolve("kotlin")) dependencies { api("fr.acinq.secp256k1:secp256k1-kmp:0.14.0") @@ -361,7 +407,7 @@ kotlin { implementation("com.google.guava:guava:30.1-jre") implementation("org.bouncycastle:bcprov-jdk15on:1.68") implementation("org.bitcoinj:bitcoinj-core:0.16.2") - + implementation("net.java.dev.jna:jna:5.13.0") } } val jvmTest by getting { @@ -400,9 +446,6 @@ kotlin { .resolve("kotlin"), secp256k1Dir .resolve("src") - .resolve("nativeMain") - .resolve("kotlin"), - uniffiBindings .resolve("nativeMain") .resolve("kotlin") ) @@ -435,7 +478,17 @@ android { namespace = "io.iohk.atala.prism.apollo" compileSdk = 34 sourceSets["main"].manifest.srcFile("src/androidMain/AndroidManifest.xml") - sourceSets["main"].jniLibs.srcDir(jniLibs) + sourceSets["main"].jniLibs { + setSrcDirs( + listOf( + project.layout.buildDirectory.asFile.get() + .resolve("generatedResources") + .resolve("android") + .resolve("main") + .resolve("jniLibs") + ) + ) + } defaultConfig { minSdk = 21 @@ -494,6 +547,9 @@ afterEvaluate { ktlint { filter { + exclude { + it.file.toString().contains("generated") + } exclude("**/external/*", "./src/jsMain/kotlin/io/iohk/atala/prism/apollo/utils/external/*") exclude { it.file.toString().contains("external") @@ -578,6 +634,18 @@ npmPublish { // Workaround for a bug in Gradle afterEvaluate { + tasks.getByName("mergeDebugJniLibFolders").dependsOn(buildEd25519Bip32Task) + tasks.getByName("packageDebugResources").dependsOn(buildEd25519Bip32Task) + tasks.getByName("extractDeepLinksForAarDebug").dependsOn(buildEd25519Bip32Task) + tasks.getByName("mergeReleaseJniLibFolders").dependsOn(buildEd25519Bip32Task) + tasks.getByName("extractDeepLinksForAarRelease").dependsOn(buildEd25519Bip32Task) + tasks.getByName("packageReleaseResources").dependsOn(buildEd25519Bip32Task) + tasks.getByName("mergeReleaseResources").dependsOn(buildEd25519Bip32Task) + tasks.getByName("compileKotlinJvm").dependsOn(buildEd25519Bip32Task) + tasks.getByName("runKtlintCheckOverAllButJSMainSourceSet").dependsOn(buildEd25519Bip32Task) + tasks.getByName("runKtlintCheckOverAndroidMainSourceSet").dependsOn(buildEd25519Bip32Task) + tasks.getByName("runKtlintCheckOverJvmMainSourceSet").dependsOn(buildEd25519Bip32Task) + if (tasks.findByName("iosX64Test") != null) { tasks.named("iosX64Test") { this.enabled = false @@ -615,4 +683,4 @@ afterEvaluate { this.enabled = false } } -} \ No newline at end of file +} diff --git a/apollo/src/allButJSMain/kotlin/io/iohk/atala/prism/apollo/derivation/EdHDKey.kt b/apollo/src/allButJSMain/kotlin/io/iohk/atala/prism/apollo/derivation/EdHDKey.kt index 115bddab4..08638bd40 100644 --- a/apollo/src/allButJSMain/kotlin/io/iohk/atala/prism/apollo/derivation/EdHDKey.kt +++ b/apollo/src/allButJSMain/kotlin/io/iohk/atala/prism/apollo/derivation/EdHDKey.kt @@ -4,7 +4,6 @@ import com.ionspin.kotlin.bignum.integer.toBigInteger import ed25519_bip32.XPrvWrapper import io.iohk.atala.prism.apollo.utils.ECConfig - /** * Represents and HDKey with its derive methods */ @@ -32,7 +31,7 @@ class EdHDKey( return EdHDKey( privateKey = wrapper.extendedSecretKey(), - chainCode = wrapper.chainCode(), + chainCode = wrapper.chainCode() ) } @@ -74,8 +73,7 @@ class EdHDKey( * @param index value used to derive a key */ fun deriveChild(wrappedIndex: BigIntegerWrapper): EdHDKey { - val extendedKey = privateKey.plus(chainCode) - val wrapper = XPrvWrapper.fromBytes(extendedKey) + val wrapper = XPrvWrapper.fromExtendedAndChaincode(privateKey, chainCode) val derived = wrapper.derive(wrappedIndex.value.uintValue()) return EdHDKey( @@ -85,4 +83,4 @@ class EdHDKey( index = wrappedIndex ) } -} \ No newline at end of file +} diff --git a/apollo/src/jsMain/kotlin/io/iohk/atala/prism/apollo/derivation/EdHDKey.kt b/apollo/src/jsMain/kotlin/io/iohk/atala/prism/apollo/derivation/EdHDKey.kt index b65ba08af..1b7894eaf 100644 --- a/apollo/src/jsMain/kotlin/io/iohk/atala/prism/apollo/derivation/EdHDKey.kt +++ b/apollo/src/jsMain/kotlin/io/iohk/atala/prism/apollo/derivation/EdHDKey.kt @@ -33,7 +33,7 @@ class EdHDKey( return EdHDKey( privateKey = wrapper.extended_secret_key(), - chainCode = wrapper.chain_code(), + chainCode = wrapper.chain_code() ) } @@ -85,4 +85,4 @@ class EdHDKey( index = wrappedIndex ) } -} \ No newline at end of file +} diff --git a/apollo/src/jsMain/kotlin/io/iohk/atala/prism/apollo/utils/external/Ed25519_Bip32.kt b/apollo/src/jsMain/kotlin/io/iohk/atala/prism/apollo/utils/external/Ed25519_Bip32.kt index 499c1b6f4..ee3b4cf3f 100644 --- a/apollo/src/jsMain/kotlin/io/iohk/atala/prism/apollo/utils/external/Ed25519_Bip32.kt +++ b/apollo/src/jsMain/kotlin/io/iohk/atala/prism/apollo/utils/external/Ed25519_Bip32.kt @@ -18,6 +18,6 @@ external interface ed25519_bip32_export { var XPrvWrapper: XPrvWrapper } -@JsModule("./ed25519_bip32_wasm.mjs") +@JsModule("./ed25519_bip32_wasm.js") @JsNonModule external val ed25519_bip32: ed25519_bip32_export diff --git a/rust-ed25519-bip32 b/rust-ed25519-bip32 new file mode 160000 index 000000000..5542ef8de --- /dev/null +++ b/rust-ed25519-bip32 @@ -0,0 +1 @@ +Subproject commit 5542ef8de79b324bbb8a060d8a8dfb08bfcfea98 From 9980325bf4316bf14c1ad192ff5ffec423a774a9 Mon Sep 17 00:00:00 2001 From: Curtish Date: Wed, 24 Apr 2024 10:18:55 +0100 Subject: [PATCH 06/39] split build.gradle --- apollo/build.ed25519bip32.gradle.kts | 150 +++++++++++++++++++ apollo/build.gradle.kts | 136 +---------------- apollo/src/nativeInterop/cinterop/uniffi.def | 13 -- 3 files changed, 153 insertions(+), 146 deletions(-) create mode 100644 apollo/build.ed25519bip32.gradle.kts delete mode 100644 apollo/src/nativeInterop/cinterop/uniffi.def diff --git a/apollo/build.ed25519bip32.gradle.kts b/apollo/build.ed25519bip32.gradle.kts new file mode 100644 index 000000000..9944638a0 --- /dev/null +++ b/apollo/build.ed25519bip32.gradle.kts @@ -0,0 +1,150 @@ +val ed25519bip32Dir = rootDir.resolve("rust-ed25519-bip32") +val taskGroup = "build ed25519-bip32" + +fun createCopyTask( + name: String, + fromDir: File, + intoDir: File +) = tasks.register(name) { + group = taskGroup + duplicatesStrategy = DuplicatesStrategy.INCLUDE + include("*.so", "*.a", "*.d", "*.dylib", "**/*.kt", "*.js") + from(fromDir) + into(intoDir) +} + +val sourceDir = ed25519bip32Dir.resolve("wrapper").resolve("target") +val buildDir = projectDir.resolve("build").resolve("generatedResources") +val generatedDir = projectDir.resolve("build").resolve("generated") + +val copyEd25519Bip32GeneratedTask = createCopyTask( + "copyEd25519Bip32Generated", + ed25519bip32Dir.resolve("wrapper").resolve("build").resolve("generated"), + generatedDir +) + +val copyEd25519Bip32ForMacOSX8664Task = createCopyTask( + "copyEd25519Bip32ForMacOSX86_64", + sourceDir.resolve("x86_64-apple-darwin").resolve("release"), + buildDir.resolve("jvm").resolve("main").resolve("darwin-x86-64") +) + +val copyEd25519Bip32ForMacOSArch64Task = createCopyTask( + "copyEd25519Bip32ForMacOSArch64", + sourceDir.resolve("aarch64-apple-darwin").resolve("release"), + buildDir.resolve("jvm").resolve("main").resolve("darwin-aarch64") +) + +val copyEd25519Bip32ForLinuxX8664Task = createCopyTask( + "copyEd25519Bip32ForLinuxX86_64", + sourceDir.resolve("x86_64-unknown-linux-gnu").resolve("release"), + buildDir.resolve("jvm").resolve("main").resolve("linux-x86-64") +) + +val copyEd25519Bip32ForLinuxArch64Task = createCopyTask( + "copyEd25519Bip32ForLinuxArch64", + sourceDir.resolve("aarch64-unknown-linux-gnu").resolve("release"), + buildDir.resolve("jvm").resolve("main").resolve("linux-aarch64") +) + +val copyEd25519Bip32ForAndroidX8664Task = createCopyTask( + "copyEd25519Bip32ForAndroidX86_64", + sourceDir.resolve("x86_64-linux-android").resolve("release"), + buildDir.resolve("android").resolve("main").resolve("jniLibs").resolve("x86_64") +) + +val copyEd25519Bip32ForAndroidArch64Task = createCopyTask( + "copyEd25519Bip32ForAndroidArch64", + sourceDir.resolve("aarch64-linux-android").resolve("release"), + buildDir.resolve("android").resolve("main").resolve("jniLibs").resolve("arm64-v8a") +) + +val copyEd25519Bip32ForAndroidI686Task = createCopyTask( + "copyEd25519Bip32ForAndroidI686", + sourceDir.resolve("i686-linux-android").resolve("release"), + buildDir.resolve("android").resolve("main").resolve("jniLibs").resolve("x86") +) + +val copyEd25519Bip32ForAndroidArmv7aTask = createCopyTask( + "copyEd25519Bip32ForAndroidArmv7a", + sourceDir.resolve("armv7-linux-androideabi").resolve("release"), + buildDir.resolve("android").resolve("main").resolve("jniLibs").resolve("armeabi-v7a") +) + +val copyEd25519Bip32Wrapper by tasks.register("copyEd25519Bip32") { + dependsOn( + copyEd25519Bip32GeneratedTask, + copyEd25519Bip32ForMacOSX8664Task, + copyEd25519Bip32ForMacOSArch64Task, + copyEd25519Bip32ForLinuxX8664Task, + copyEd25519Bip32ForLinuxArch64Task, + copyEd25519Bip32ForAndroidX8664Task, + copyEd25519Bip32ForAndroidArch64Task, + copyEd25519Bip32ForAndroidI686Task, + copyEd25519Bip32ForAndroidArmv7aTask + ) + mustRunAfter(buildEd25519Bip32Wrapper) +} + +val buildEd25519Bip32Wrapper by tasks.register("buildEd25519Bip32Wrapper") { + group = taskGroup + workingDir = ed25519bip32Dir.resolve("wrapper") + commandLine("./build-kotlin-library.sh") +} + +val copyEd25519Bip32Wasm = createCopyTask( + "copyEd25519Bip32GeneratedWasm", + ed25519bip32Dir.resolve("wasm").resolve("build"), + projectDir.resolve("build").resolve("js").resolve("packages").resolve("Apollo").resolve("kotlin") +) +copyEd25519Bip32Wasm.configure { + mustRunAfter(buildEd25519Bip32Wasm) +} + +val buildEd25519Bip32Wasm by tasks.register("buildEd25519Bip32Wasm") { + group = taskGroup + workingDir = ed25519bip32Dir.resolve("wasm") + commandLine("./build_kotlin_library.sh") +} + +val buildEd25519Bip32Task by tasks.register("buildEd25519Bip32") { + group = taskGroup + dependsOn(buildEd25519Bip32Wasm, copyEd25519Bip32Wasm, buildEd25519Bip32Wrapper, copyEd25519Bip32Wrapper) +} + +val cleanEd25519Bip32 by tasks.register("cleanEd25519Bip32") { + group = taskGroup + val wasmDir = ed25519bip32Dir.resolve("wasm") + delete.add(wasmDir.resolve("build")) + delete.add(wasmDir.resolve("pkg")) + delete.add(wasmDir.resolve("node_modules")) + delete.add(wasmDir.resolve("target")) + + val wrapperDir = ed25519bip32Dir.resolve("wrapper") + delete.add(wrapperDir.resolve("build")) + delete.add(wrapperDir.resolve("target")) +} + +tasks { + getByName("clean") { + dependsOn(cleanEd25519Bip32) + } + + withType { + dependsOn(buildEd25519Bip32Task) + } +} + +afterEvaluate { + tasks.getByName("mergeDebugJniLibFolders").dependsOn(buildEd25519Bip32Task) + tasks.getByName("packageDebugResources").dependsOn(buildEd25519Bip32Task) + tasks.getByName("extractDeepLinksForAarDebug").dependsOn(buildEd25519Bip32Task) + tasks.getByName("mergeReleaseJniLibFolders").dependsOn(buildEd25519Bip32Task) + tasks.getByName("extractDeepLinksForAarRelease").dependsOn(buildEd25519Bip32Task) + tasks.getByName("packageReleaseResources").dependsOn(buildEd25519Bip32Task) + tasks.getByName("mergeReleaseResources").dependsOn(buildEd25519Bip32Task) + tasks.getByName("compileKotlinJvm").dependsOn(buildEd25519Bip32Task) + tasks.getByName("runKtlintCheckOverAllButJSMainSourceSet").dependsOn(buildEd25519Bip32Task) + tasks.getByName("runKtlintCheckOverAndroidMainSourceSet").dependsOn(buildEd25519Bip32Task) + tasks.getByName("runKtlintCheckOverJvmMainSourceSet").dependsOn(buildEd25519Bip32Task) +} diff --git a/apollo/build.gradle.kts b/apollo/build.gradle.kts index 17e130fba..654f664c5 100644 --- a/apollo/build.gradle.kts +++ b/apollo/build.gradle.kts @@ -12,7 +12,7 @@ import java.time.Year val currentModuleName: String = "Apollo" val os: OperatingSystem = OperatingSystem.current() val secp256k1Dir = rootDir.resolve("secp256k1-kmp") -val ed25519bip32Dir = rootDir.resolve("rust-ed25519-bip32") +val generatedDir = projectDir.resolve("build").resolve("generated") plugins { kotlin("multiplatform") @@ -22,6 +22,8 @@ plugins { id("dev.petuska.npm.publish") version "3.4.1" } +apply(from = "build.ed25519bip32.gradle.kts") + /** * Adds a Swift interop configuration for a library. * @@ -81,121 +83,6 @@ val javadocJar by tasks.registering(Jar::class) { from(tasks.dokkaHtml) } -fun createCopyTask( - name: String, - fromDir: File, - intoDir: File -) = tasks.register(name) { - group = "build-Ed25519-Bip32" - duplicatesStrategy = DuplicatesStrategy.INCLUDE - include("*.so", "*.a", "*.d", "*.dylib", "**/*.kt", "*.js") - from(fromDir) - into(intoDir) -} - -val sourceDir = ed25519bip32Dir.resolve("wrapper").resolve("target") -val buildDir = projectDir.resolve("build").resolve("generatedResources") -val generatedDir = projectDir.resolve("build").resolve("generated") - -val copyEd25519Bip32GeneratedTask = createCopyTask( - "copyEd25519Bip32Generated", - ed25519bip32Dir.resolve("wrapper").resolve("build").resolve("generated"), - generatedDir -) - -val copyEd25519Bip32ForMacOSX8664Task = createCopyTask( - "copyEd25519Bip32ForMacOSX86_64", - sourceDir.resolve("x86_64-apple-darwin").resolve("release"), - buildDir.resolve("jvm").resolve("main").resolve("darwin-x86-64") -) - -val copyEd25519Bip32ForMacOSArch64Task = createCopyTask( - "copyEd25519Bip32ForMacOSArch64", - sourceDir.resolve("aarch64-apple-darwin").resolve("release"), - buildDir.resolve("jvm").resolve("main").resolve("darwin-aarch64") -) - -val copyEd25519Bip32ForLinuxX8664Task = createCopyTask( - "copyEd25519Bip32ForLinuxX86_64", - sourceDir.resolve("x86_64-unknown-linux-gnu").resolve("release"), - buildDir.resolve("jvm").resolve("main").resolve("linux-x86-64") -) - -val copyEd25519Bip32ForLinuxArch64Task = createCopyTask( - "copyEd25519Bip32ForLinuxArch64", - sourceDir.resolve("aarch64-unknown-linux-gnu").resolve("release"), - buildDir.resolve("jvm").resolve("main").resolve("linux-aarch64") -) - -val copyEd25519Bip32ForAndroidX8664Task = createCopyTask( - "copyEd25519Bip32ForAndroidX86_64", - sourceDir.resolve("x86_64-linux-android").resolve("release"), - buildDir.resolve("android").resolve("main").resolve("jniLibs").resolve("x86_64") -) - -val copyEd25519Bip32ForAndroidArch64Task = createCopyTask( - "copyEd25519Bip32ForAndroidArch64", - sourceDir.resolve("aarch64-linux-android").resolve("release"), - buildDir.resolve("android").resolve("main").resolve("jniLibs").resolve("arm64-v8a") -) - -val copyEd25519Bip32ForAndroidI686Task = createCopyTask( - "copyEd25519Bip32ForAndroidI686", - sourceDir.resolve("i686-linux-android").resolve("release"), - buildDir.resolve("android").resolve("main").resolve("jniLibs").resolve("x86") -) - -val copyEd25519Bip32ForAndroidArmv7aTask = createCopyTask( - "copyEd25519Bip32ForAndroidArmv7a", - sourceDir.resolve("armv7-linux-androideabi").resolve("release"), - buildDir.resolve("android").resolve("main").resolve("jniLibs").resolve("armeabi-v7a") -) - -val copyEd25519Bip32Wrapper by tasks.register("copyEd25519Bip32") { - dependsOn( - copyEd25519Bip32GeneratedTask, - copyEd25519Bip32ForMacOSX8664Task, - copyEd25519Bip32ForMacOSArch64Task, - copyEd25519Bip32ForLinuxX8664Task, - copyEd25519Bip32ForLinuxArch64Task, - copyEd25519Bip32ForAndroidX8664Task, - copyEd25519Bip32ForAndroidArch64Task, - copyEd25519Bip32ForAndroidI686Task, - copyEd25519Bip32ForAndroidArmv7aTask - ) - mustRunAfter(buildEd25519Bip32Wrapper) -} - -val buildEd25519Bip32Wrapper by tasks.register("buildEd25519Bip32Wrapper") { - group = "build-Ed25519-Bip32" - workingDir = ed25519bip32Dir.resolve("wrapper") - commandLine("./build-kotlin-library.sh") -} - -val copyEd25519Bip32Wasm = createCopyTask( - "copyEd25519Bip32GeneratedWasm", - ed25519bip32Dir.resolve("wasm").resolve("build"), - projectDir.resolve("build").resolve("js").resolve("packages").resolve("Apollo").resolve("kotlin") -) -copyEd25519Bip32Wasm.configure { - mustRunAfter(buildEd25519Bip32Wasm) -} - -val buildEd25519Bip32Wasm by tasks.register("buildEd25519Bip32Wasm") { - group = "build-Ed25519-Bip32" - workingDir = ed25519bip32Dir.resolve("wasm") - commandLine("./build_kotlin_library.sh") -} - -val buildEd25519Bip32Task by tasks.register("buildEd25519Bip32") { - group = "build-Ed25519-Bip32" - dependsOn(buildEd25519Bip32Wasm, copyEd25519Bip32Wasm, buildEd25519Bip32Wrapper, copyEd25519Bip32Wrapper) -} - -tasks.withType { - dependsOn(buildEd25519Bip32Task) -} - kotlin { androidTarget { publishAllLibraryVariants() @@ -450,11 +337,6 @@ kotlin { .resolve("kotlin") ) } - - all { - languageSettings.optIn("kotlin.RequiresOptIn") - languageSettings.optIn("kotlinx.cinterop.ExperimentalForeignApi") - } } // Enable the export of KDoc (Experimental feature) to Generated Native targets (Apple, Linux, etc.) @@ -634,18 +516,6 @@ npmPublish { // Workaround for a bug in Gradle afterEvaluate { - tasks.getByName("mergeDebugJniLibFolders").dependsOn(buildEd25519Bip32Task) - tasks.getByName("packageDebugResources").dependsOn(buildEd25519Bip32Task) - tasks.getByName("extractDeepLinksForAarDebug").dependsOn(buildEd25519Bip32Task) - tasks.getByName("mergeReleaseJniLibFolders").dependsOn(buildEd25519Bip32Task) - tasks.getByName("extractDeepLinksForAarRelease").dependsOn(buildEd25519Bip32Task) - tasks.getByName("packageReleaseResources").dependsOn(buildEd25519Bip32Task) - tasks.getByName("mergeReleaseResources").dependsOn(buildEd25519Bip32Task) - tasks.getByName("compileKotlinJvm").dependsOn(buildEd25519Bip32Task) - tasks.getByName("runKtlintCheckOverAllButJSMainSourceSet").dependsOn(buildEd25519Bip32Task) - tasks.getByName("runKtlintCheckOverAndroidMainSourceSet").dependsOn(buildEd25519Bip32Task) - tasks.getByName("runKtlintCheckOverJvmMainSourceSet").dependsOn(buildEd25519Bip32Task) - if (tasks.findByName("iosX64Test") != null) { tasks.named("iosX64Test") { this.enabled = false diff --git a/apollo/src/nativeInterop/cinterop/uniffi.def b/apollo/src/nativeInterop/cinterop/uniffi.def deleted file mode 100644 index 7f7127c4d..000000000 --- a/apollo/src/nativeInterop/cinterop/uniffi.def +++ /dev/null @@ -1,13 +0,0 @@ -package = ed25519_bip32.cinterop -headers = ed25519_bip32.h -headerFilter = ** - -staticLibraries.ios = libed25519_bip32_wrapper.a - - -libraryPaths.ios_x64 = ../../rust-ed25519-bip32/wrapper/target/x86_64-apple-ios/release -libraryPaths.ios_arm64 = ../../rust-ed25519-bip32/wrapper/target/aarch64-apple-ios/release -libraryPaths.ios_simulator_arm64 = ../../rust-ed25519-bip32/wrapper/target/aarch64-apple-ios-sim/release - -staticLibraries.osx = libed25519_bip32_wrapper.a -libraryPaths.osx = ../../rust-ed25519-bip32/wrapper/out/kmpp-uniffi/macos-native/static \ No newline at end of file From ee64f52d7137272394fb685edf4f105fb962b66c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Francisco=20Javier=20Ribo=CC=81=20Labrador?= Date: Thu, 25 Apr 2024 17:01:44 +0200 Subject: [PATCH 07/39] fix: improve build gradle. --- apollo/build.ed25519bip32.gradle.kts | 1 + apollo/build.gradle.kts | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/apollo/build.ed25519bip32.gradle.kts b/apollo/build.ed25519bip32.gradle.kts index 9944638a0..336fe2081 100644 --- a/apollo/build.ed25519bip32.gradle.kts +++ b/apollo/build.ed25519bip32.gradle.kts @@ -136,6 +136,7 @@ tasks { } afterEvaluate { + tasks.getByName("compileKotlinIosArm64").dependsOn(buildEd25519Bip32Task) tasks.getByName("mergeDebugJniLibFolders").dependsOn(buildEd25519Bip32Task) tasks.getByName("packageDebugResources").dependsOn(buildEd25519Bip32Task) tasks.getByName("extractDeepLinksForAarDebug").dependsOn(buildEd25519Bip32Task) diff --git a/apollo/build.gradle.kts b/apollo/build.gradle.kts index 654f664c5..d409dba3c 100644 --- a/apollo/build.gradle.kts +++ b/apollo/build.gradle.kts @@ -336,6 +336,11 @@ kotlin { .resolve("nativeMain") .resolve("kotlin") ) + + } + + all { + languageSettings.optIn("kotlinx.cinterop.ExperimentalForeignApi") } } From ede1d3c5ee5c919c2b1b671899e70bf610b37adc Mon Sep 17 00:00:00 2001 From: Ahmed Moussa Date: Tue, 30 Apr 2024 11:24:32 +0400 Subject: [PATCH 08/39] fix: Handle some compilation issues - Fixed a couple of linked issues - Fixed missing def file - Fixed depends on issue that happened from creating a new source set while using DefaultHierarchyTemplate - Fixed not having Android Src folder - Fixed missing header file on copying files - Fixed missing CInterop method Signed-off-by: Ahmed Moussa --- apollo/build.ed25519bip32.gradle.kts | 151 -------- apollo/build.gradle.kts | 355 ++++++++++++++++-- .../nativeInterop/cinterop/ed25519_bip32.def | 1 + 3 files changed, 331 insertions(+), 176 deletions(-) delete mode 100644 apollo/build.ed25519bip32.gradle.kts create mode 100644 apollo/src/nativeInterop/cinterop/ed25519_bip32.def diff --git a/apollo/build.ed25519bip32.gradle.kts b/apollo/build.ed25519bip32.gradle.kts deleted file mode 100644 index 336fe2081..000000000 --- a/apollo/build.ed25519bip32.gradle.kts +++ /dev/null @@ -1,151 +0,0 @@ -val ed25519bip32Dir = rootDir.resolve("rust-ed25519-bip32") -val taskGroup = "build ed25519-bip32" - -fun createCopyTask( - name: String, - fromDir: File, - intoDir: File -) = tasks.register(name) { - group = taskGroup - duplicatesStrategy = DuplicatesStrategy.INCLUDE - include("*.so", "*.a", "*.d", "*.dylib", "**/*.kt", "*.js") - from(fromDir) - into(intoDir) -} - -val sourceDir = ed25519bip32Dir.resolve("wrapper").resolve("target") -val buildDir = projectDir.resolve("build").resolve("generatedResources") -val generatedDir = projectDir.resolve("build").resolve("generated") - -val copyEd25519Bip32GeneratedTask = createCopyTask( - "copyEd25519Bip32Generated", - ed25519bip32Dir.resolve("wrapper").resolve("build").resolve("generated"), - generatedDir -) - -val copyEd25519Bip32ForMacOSX8664Task = createCopyTask( - "copyEd25519Bip32ForMacOSX86_64", - sourceDir.resolve("x86_64-apple-darwin").resolve("release"), - buildDir.resolve("jvm").resolve("main").resolve("darwin-x86-64") -) - -val copyEd25519Bip32ForMacOSArch64Task = createCopyTask( - "copyEd25519Bip32ForMacOSArch64", - sourceDir.resolve("aarch64-apple-darwin").resolve("release"), - buildDir.resolve("jvm").resolve("main").resolve("darwin-aarch64") -) - -val copyEd25519Bip32ForLinuxX8664Task = createCopyTask( - "copyEd25519Bip32ForLinuxX86_64", - sourceDir.resolve("x86_64-unknown-linux-gnu").resolve("release"), - buildDir.resolve("jvm").resolve("main").resolve("linux-x86-64") -) - -val copyEd25519Bip32ForLinuxArch64Task = createCopyTask( - "copyEd25519Bip32ForLinuxArch64", - sourceDir.resolve("aarch64-unknown-linux-gnu").resolve("release"), - buildDir.resolve("jvm").resolve("main").resolve("linux-aarch64") -) - -val copyEd25519Bip32ForAndroidX8664Task = createCopyTask( - "copyEd25519Bip32ForAndroidX86_64", - sourceDir.resolve("x86_64-linux-android").resolve("release"), - buildDir.resolve("android").resolve("main").resolve("jniLibs").resolve("x86_64") -) - -val copyEd25519Bip32ForAndroidArch64Task = createCopyTask( - "copyEd25519Bip32ForAndroidArch64", - sourceDir.resolve("aarch64-linux-android").resolve("release"), - buildDir.resolve("android").resolve("main").resolve("jniLibs").resolve("arm64-v8a") -) - -val copyEd25519Bip32ForAndroidI686Task = createCopyTask( - "copyEd25519Bip32ForAndroidI686", - sourceDir.resolve("i686-linux-android").resolve("release"), - buildDir.resolve("android").resolve("main").resolve("jniLibs").resolve("x86") -) - -val copyEd25519Bip32ForAndroidArmv7aTask = createCopyTask( - "copyEd25519Bip32ForAndroidArmv7a", - sourceDir.resolve("armv7-linux-androideabi").resolve("release"), - buildDir.resolve("android").resolve("main").resolve("jniLibs").resolve("armeabi-v7a") -) - -val copyEd25519Bip32Wrapper by tasks.register("copyEd25519Bip32") { - dependsOn( - copyEd25519Bip32GeneratedTask, - copyEd25519Bip32ForMacOSX8664Task, - copyEd25519Bip32ForMacOSArch64Task, - copyEd25519Bip32ForLinuxX8664Task, - copyEd25519Bip32ForLinuxArch64Task, - copyEd25519Bip32ForAndroidX8664Task, - copyEd25519Bip32ForAndroidArch64Task, - copyEd25519Bip32ForAndroidI686Task, - copyEd25519Bip32ForAndroidArmv7aTask - ) - mustRunAfter(buildEd25519Bip32Wrapper) -} - -val buildEd25519Bip32Wrapper by tasks.register("buildEd25519Bip32Wrapper") { - group = taskGroup - workingDir = ed25519bip32Dir.resolve("wrapper") - commandLine("./build-kotlin-library.sh") -} - -val copyEd25519Bip32Wasm = createCopyTask( - "copyEd25519Bip32GeneratedWasm", - ed25519bip32Dir.resolve("wasm").resolve("build"), - projectDir.resolve("build").resolve("js").resolve("packages").resolve("Apollo").resolve("kotlin") -) -copyEd25519Bip32Wasm.configure { - mustRunAfter(buildEd25519Bip32Wasm) -} - -val buildEd25519Bip32Wasm by tasks.register("buildEd25519Bip32Wasm") { - group = taskGroup - workingDir = ed25519bip32Dir.resolve("wasm") - commandLine("./build_kotlin_library.sh") -} - -val buildEd25519Bip32Task by tasks.register("buildEd25519Bip32") { - group = taskGroup - dependsOn(buildEd25519Bip32Wasm, copyEd25519Bip32Wasm, buildEd25519Bip32Wrapper, copyEd25519Bip32Wrapper) -} - -val cleanEd25519Bip32 by tasks.register("cleanEd25519Bip32") { - group = taskGroup - val wasmDir = ed25519bip32Dir.resolve("wasm") - delete.add(wasmDir.resolve("build")) - delete.add(wasmDir.resolve("pkg")) - delete.add(wasmDir.resolve("node_modules")) - delete.add(wasmDir.resolve("target")) - - val wrapperDir = ed25519bip32Dir.resolve("wrapper") - delete.add(wrapperDir.resolve("build")) - delete.add(wrapperDir.resolve("target")) -} - -tasks { - getByName("clean") { - dependsOn(cleanEd25519Bip32) - } - - withType { - dependsOn(buildEd25519Bip32Task) - } -} - -afterEvaluate { - tasks.getByName("compileKotlinIosArm64").dependsOn(buildEd25519Bip32Task) - tasks.getByName("mergeDebugJniLibFolders").dependsOn(buildEd25519Bip32Task) - tasks.getByName("packageDebugResources").dependsOn(buildEd25519Bip32Task) - tasks.getByName("extractDeepLinksForAarDebug").dependsOn(buildEd25519Bip32Task) - tasks.getByName("mergeReleaseJniLibFolders").dependsOn(buildEd25519Bip32Task) - tasks.getByName("extractDeepLinksForAarRelease").dependsOn(buildEd25519Bip32Task) - tasks.getByName("packageReleaseResources").dependsOn(buildEd25519Bip32Task) - tasks.getByName("mergeReleaseResources").dependsOn(buildEd25519Bip32Task) - tasks.getByName("compileKotlinJvm").dependsOn(buildEd25519Bip32Task) - tasks.getByName("runKtlintCheckOverAllButJSMainSourceSet").dependsOn(buildEd25519Bip32Task) - tasks.getByName("runKtlintCheckOverAndroidMainSourceSet").dependsOn(buildEd25519Bip32Task) - tasks.getByName("runKtlintCheckOverJvmMainSourceSet").dependsOn(buildEd25519Bip32Task) -} diff --git a/apollo/build.gradle.kts b/apollo/build.gradle.kts index d409dba3c..594309a45 100644 --- a/apollo/build.gradle.kts +++ b/apollo/build.gradle.kts @@ -8,11 +8,18 @@ import org.jetbrains.kotlin.gradle.tasks.CInteropProcess import org.jetbrains.kotlin.gradle.tasks.KotlinCompile import java.net.URL import java.time.Year +import org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi +import org.jlleitschuh.gradle.ktlint.tasks.KtLintCheckTask val currentModuleName: String = "Apollo" val os: OperatingSystem = OperatingSystem.current() val secp256k1Dir = rootDir.resolve("secp256k1-kmp") -val generatedDir = projectDir.resolve("build").resolve("generated") + +val taskGroup = "build ed25519-bip32" +val ed25519bip32Dir = rootDir.resolve("rust-ed25519-bip32") +val generatedDir = project.layout.buildDirectory.asFile.get().resolve("generated") +val sourceDir = ed25519bip32Dir.resolve("wrapper").resolve("target") +val generatedResourcesDir = projectDir.resolve("build").resolve("generatedResources") plugins { kotlin("multiplatform") @@ -22,8 +29,6 @@ plugins { id("dev.petuska.npm.publish") version "3.4.1" } -apply(from = "build.ed25519bip32.gradle.kts") - /** * Adds a Swift interop configuration for a library. * @@ -73,6 +78,126 @@ fun KotlinNativeTarget.secp256k1CInterop(target: String) { } } +/** + * Generates the cinterop configuration for the ed25519Bip32 library based on the target platform. + * + * @param target The target platform for which the cinterop configuration is generated. + * Supported values are "macosX64", "macosArm64", "iosArm64", "iosX64", and "iosSimulatorArm64". + * + * @throws GradleException if an unsupported target platform is specified. + */ +fun KotlinNativeTarget.ed25519Bip32CInterop(target: String) { + compilations.getByName("main") { + cinterops { + val ed25519_bip32 by creating { + val crate = this.name + packageName("$crate.cinterop") + header( + project.layout.buildDirectory.asFile.get() + .resolve("generated") + .resolve("nativeInterop") + .resolve("cinterop") + .resolve("headers") + .resolve(crate) + .resolve("$crate.h") + ) + tasks.named(interopProcessingTaskName) { + dependsOn(":apollo:buildEd25519Bip32") + } + when (target) { + "macosX64" -> { + extraOpts( + "-libraryPath", + rootDir + .resolve("rust-ed25519-bip32") + .resolve("wrapper") + .resolve("target") + .resolve("x86_64-apple-darwin") + .resolve("release") + .absolutePath + ) + } + + "macosArm64" -> { + extraOpts( + "-libraryPath", + rootDir + .resolve("rust-ed25519-bip32") + .resolve("wrapper") + .resolve("target") + .resolve("aarch64-apple-darwin") + .resolve("release") + .absolutePath + ) + } + + "iosArm64" -> { + extraOpts( + "-libraryPath", + rootDir + .resolve("rust-ed25519-bip32") + .resolve("wrapper") + .resolve("target") + .resolve("aarch64-apple-ios") + .resolve("release") + .absolutePath + ) + } + + "iosX64" -> { + extraOpts( + "-libraryPath", + rootDir + .resolve("rust-ed25519-bip32") + .resolve("wrapper") + .resolve("target") + .resolve("x86_64-apple-ios") + .resolve("release") + .absolutePath + ) + } + + "iosSimulatorArm64" -> { + extraOpts( + "-libraryPath", + rootDir + .resolve("rust-ed25519-bip32") + .resolve("wrapper") + .resolve("target") + .resolve("aarch64-apple-ios-sim") + .resolve("release") + .absolutePath + ) + } + + else -> { + throw GradleException("Unsupported linking for $target") + } + } + } + } + } +} + +/** + * Creates a copy task with the specified parameters. + * + * @param name The name of the copy task. + * @param fromDir The source directory from which files will be copied. + * @param intoDir The destination directory where files will be copied into. + */ +fun createCopyTask( + name: String, + fromDir: File, + intoDir: File +) = tasks.register(name) { + group = taskGroup + duplicatesStrategy = DuplicatesStrategy.INCLUDE + include("*.so", "*.a", "*.d", "*.dylib", "**/*.kt", "*.js", "**/*.h") + from(fromDir) + into(intoDir) +} + /** * The `javadocJar` variable is used to register a `Jar` task to generate a Javadoc JAR file. * The Javadoc JAR file is created with the classifier "javadoc" and it includes the HTML documentation generated @@ -83,6 +208,125 @@ val javadocJar by tasks.registering(Jar::class) { from(tasks.dokkaHtml) } +val copyEd25519Bip32GeneratedTask = createCopyTask( + "copyEd25519Bip32Generated", + ed25519bip32Dir.resolve("wrapper").resolve("build").resolve("generated"), + generatedDir +) + +val copyToAndroidSrc by tasks.register("copyToAndroidSrc") { + group = taskGroup + duplicatesStrategy = DuplicatesStrategy.INCLUDE + include("*.so", "*.a", "*.d", "*.dylib", "**/*.kt", "*.js", "**/*.h") + from(project.layout.buildDirectory.asFile.get().resolve("generated").resolve("jvmMain")) + into(project.layout.buildDirectory.asFile.get().resolve("generated").resolve("androidMain")) + dependsOn(copyEd25519Bip32GeneratedTask) + mustRunAfter(copyEd25519Bip32GeneratedTask) +} + +val copyEd25519Bip32ForMacOSX8664Task = createCopyTask( + "copyEd25519Bip32ForMacOSX86_64", + sourceDir.resolve("x86_64-apple-darwin").resolve("release"), + generatedResourcesDir.resolve("jvm").resolve("main").resolve("darwin-x86-64") +) + +val copyEd25519Bip32ForMacOSArch64Task = createCopyTask( + "copyEd25519Bip32ForMacOSArch64", + sourceDir.resolve("aarch64-apple-darwin").resolve("release"), + generatedResourcesDir.resolve("jvm").resolve("main").resolve("darwin-aarch64") +) + +val copyEd25519Bip32ForLinuxX8664Task = createCopyTask( + "copyEd25519Bip32ForLinuxX86_64", + sourceDir.resolve("x86_64-unknown-linux-gnu").resolve("release"), + generatedResourcesDir.resolve("jvm").resolve("main").resolve("linux-x86-64") +) + +val copyEd25519Bip32ForLinuxArch64Task = createCopyTask( + "copyEd25519Bip32ForLinuxArch64", + sourceDir.resolve("aarch64-unknown-linux-gnu").resolve("release"), + generatedResourcesDir.resolve("jvm").resolve("main").resolve("linux-aarch64") +) + +val copyEd25519Bip32ForAndroidX8664Task = createCopyTask( + "copyEd25519Bip32ForAndroidX86_64", + sourceDir.resolve("x86_64-linux-android").resolve("release"), + generatedResourcesDir.resolve("android").resolve("main").resolve("jniLibs").resolve("x86_64") +) + +val copyEd25519Bip32ForAndroidArch64Task = createCopyTask( + "copyEd25519Bip32ForAndroidArch64", + sourceDir.resolve("aarch64-linux-android").resolve("release"), + generatedResourcesDir.resolve("android").resolve("main").resolve("jniLibs").resolve("arm64-v8a") +) + +val copyEd25519Bip32ForAndroidI686Task = createCopyTask( + "copyEd25519Bip32ForAndroidI686", + sourceDir.resolve("i686-linux-android").resolve("release"), + generatedResourcesDir.resolve("android").resolve("main").resolve("jniLibs").resolve("x86") +) + +val copyEd25519Bip32ForAndroidArmv7aTask = createCopyTask( + "copyEd25519Bip32ForAndroidArmv7a", + sourceDir.resolve("armv7-linux-androideabi").resolve("release"), + generatedResourcesDir.resolve("android").resolve("main").resolve("jniLibs").resolve("armeabi-v7a") +) + +val copyEd25519Bip32Wrapper by tasks.register("copyEd25519Bip32") { + dependsOn( + copyEd25519Bip32GeneratedTask, + copyEd25519Bip32ForMacOSX8664Task, + copyEd25519Bip32ForMacOSArch64Task, + copyEd25519Bip32ForLinuxX8664Task, + copyEd25519Bip32ForLinuxArch64Task, + copyEd25519Bip32ForAndroidX8664Task, + copyEd25519Bip32ForAndroidArch64Task, + copyEd25519Bip32ForAndroidI686Task, + copyEd25519Bip32ForAndroidArmv7aTask, + copyToAndroidSrc + ) + mustRunAfter(buildEd25519Bip32Wrapper) +} + +val buildEd25519Bip32Wrapper by tasks.register("buildEd25519Bip32Wrapper") { + group = taskGroup + workingDir = ed25519bip32Dir.resolve("wrapper") + commandLine("./build-kotlin-library.sh") +} + +val copyEd25519Bip32Wasm = createCopyTask( + "copyEd25519Bip32GeneratedWasm", + ed25519bip32Dir.resolve("wasm").resolve("build"), + projectDir.resolve("build").resolve("js").resolve("packages").resolve("Apollo").resolve("kotlin") +) +copyEd25519Bip32Wasm.configure { + mustRunAfter(buildEd25519Bip32Wasm) +} + +val buildEd25519Bip32Wasm by tasks.register("buildEd25519Bip32Wasm") { + group = taskGroup + workingDir = ed25519bip32Dir.resolve("wasm") + commandLine("./build_kotlin_library.sh") +} + +val buildEd25519Bip32Task by tasks.register("buildEd25519Bip32") { + group = taskGroup + dependsOn(buildEd25519Bip32Wasm, copyEd25519Bip32Wasm, buildEd25519Bip32Wrapper, copyEd25519Bip32Wrapper) +} + +val cleanEd25519Bip32 by tasks.register("cleanEd25519Bip32") { + group = taskGroup + val wasmDir = ed25519bip32Dir.resolve("wasm") + delete.add(wasmDir.resolve("build")) + delete.add(wasmDir.resolve("pkg")) + delete.add(wasmDir.resolve("node_modules")) + delete.add(wasmDir.resolve("target")) + + val wrapperDir = ed25519bip32Dir.resolve("wrapper") + delete.add(wrapperDir.resolve("build")) + delete.add(wrapperDir.resolve("target")) +} + kotlin { androidTarget { publishAllLibraryVariants() @@ -110,6 +354,8 @@ kotlin { swiftCinterop("IOHKCryptoKit", name) secp256k1CInterop("ios") + ed25519Bip32CInterop(name) + // https://youtrack.jetbrains.com/issue/KT-39396 compilations["main"].kotlinOptions.freeCompilerArgs += listOf( "-include-binary", @@ -130,7 +376,10 @@ kotlin { iosX64 { swiftCinterop("IOHKSecureRandomGeneration", name) swiftCinterop("IOHKCryptoKit", name) + secp256k1CInterop("ios") + ed25519Bip32CInterop(name) + // https://youtrack.jetbrains.com/issue/KT-39396 compilations["main"].kotlinOptions.freeCompilerArgs += listOf( "-include-binary", @@ -158,6 +407,8 @@ kotlin { swiftCinterop("IOHKCryptoKit", name) secp256k1CInterop("ios") + ed25519Bip32CInterop(name) + // https://youtrack.jetbrains.com/issue/KT-39396 compilations["main"].kotlinOptions.freeCompilerArgs += listOf( "-include-binary", @@ -180,6 +431,8 @@ kotlin { swiftCinterop("IOHKCryptoKit", name) secp256k1CInterop("macosArm64") + ed25519Bip32CInterop(name) + // https://youtrack.jetbrains.com/issue/KT-39396 compilations["main"].kotlinOptions.freeCompilerArgs += listOf( "-include-binary", @@ -246,8 +499,8 @@ kotlin { implementation("com.ionspin.kotlin:bignum:0.3.9") implementation("org.kotlincrypto.macs:hmac-sha2:0.3.0") implementation("org.kotlincrypto.hash:sha2:0.4.0") - implementation("com.squareup.okio:okio:3.2.0") - implementation("org.jetbrains.kotlinx:atomicfu:0.22.0") + implementation("com.squareup.okio:okio:3.7.0") + implementation("org.jetbrains.kotlinx:atomicfu:0.23.1") } } val commonTest by getting { @@ -255,19 +508,30 @@ kotlin { implementation(kotlin("test")) } } - val allButJSMain by creating { - this.dependsOn(commonMain) - kotlin.srcDir(generatedDir.resolve("commonMain").resolve("kotlin")) + dependsOn(commonMain) + kotlin.srcDir( + generatedDir + .resolve("commonMain") + .resolve("kotlin") + ) } val allButJSTest by creating { - this.dependsOn(commonTest) + dependsOn(commonTest) } - val androidMain by getting { - this.dependsOn(allButJSMain) - kotlin.srcDir(generatedDir.resolve("jvmMain").resolve("kotlin")) - + dependsOn(allButJSMain) + kotlin.srcDir( + generatedDir + .resolve("androidMain") + .resolve("kotlin") + ) + val generatedResources = project.layout.buildDirectory.asFile.get() + .resolve("generatedResources") + .resolve("android") + .resolve("main") + .resolve("jniLibs") + resources.srcDir(generatedResources) dependencies { api("fr.acinq.secp256k1:secp256k1-kmp:0.14.0") implementation("fr.acinq.secp256k1:secp256k1-kmp-jni-jvm:0.11.0") @@ -279,15 +543,23 @@ kotlin { } } val androidUnitTest by getting { - this.dependsOn(allButJSTest) + dependsOn(allButJSTest) dependencies { implementation("junit:junit:4.13.2") } } val jvmMain by getting { - this.dependsOn(allButJSMain) - kotlin.srcDir(generatedDir.resolve("jvmMain").resolve("kotlin")) - + dependsOn(allButJSMain) + kotlin.srcDir( + generatedDir + .resolve("jvmMain") + .resolve("kotlin") + ) + val generatedResources = project.layout.buildDirectory.asFile.get() + .resolve("generatedResources") + .resolve("jvm") + .resolve("main") + resources.srcDir(generatedResources) dependencies { api("fr.acinq.secp256k1:secp256k1-kmp:0.14.0") implementation("fr.acinq.secp256k1:secp256k1-kmp-jni-jvm:0.11.0") @@ -298,8 +570,7 @@ kotlin { } } val jvmTest by getting { - this.dependsOn(allButJSTest) - + dependsOn(allButJSTest) dependencies { implementation("junit:junit:4.13.2") } @@ -322,10 +593,15 @@ kotlin { } } val jsTest by getting - + val nativeMain by getting { + dependsOn(allButJSMain) + kotlin.srcDir( + generatedDir + .resolve("nativeMain") + .resolve("kotlin") + ) + } val appleMain by getting { - this.dependsOn(allButJSMain) - kotlin.srcDirs( secp256k1Dir .resolve("src") @@ -336,16 +612,23 @@ kotlin { .resolve("nativeMain") .resolve("kotlin") ) - } all { - languageSettings.optIn("kotlinx.cinterop.ExperimentalForeignApi") + languageSettings { + optIn("kotlin.RequiresOptIn") + optIn("kotlinx.cinterop.ExperimentalForeignApi") + } } } + @OptIn(ExperimentalKotlinGradlePluginApi::class) + compilerOptions { + freeCompilerArgs.add("-Xexpect-actual-classes") + } + // Enable the export of KDoc (Experimental feature) to Generated Native targets (Apple, Linux, etc.) - targets.withType { + targets.withType { compilations.getByName("main") { compilerOptions.options.freeCompilerArgs.add("-Xexport-kdoc") } @@ -521,6 +804,28 @@ npmPublish { // Workaround for a bug in Gradle afterEvaluate { + tasks.getByName("clean") { + // dependsOn(cleanEd25519Bip32) + } + tasks.withType { + dependsOn(buildEd25519Bip32Task) + } + tasks.withType { + dependsOn(copyEd25519Bip32GeneratedTask) + } + tasks.withType { + dependsOn(buildEd25519Bip32Task) + } + tasks.withType { + dependsOn(buildEd25519Bip32Task) + } + tasks.getByName("mergeDebugJniLibFolders").dependsOn(buildEd25519Bip32Task) + tasks.getByName("packageDebugResources").dependsOn(buildEd25519Bip32Task) + tasks.getByName("extractDeepLinksForAarDebug").dependsOn(buildEd25519Bip32Task) + tasks.getByName("mergeReleaseJniLibFolders").dependsOn(buildEd25519Bip32Task) + tasks.getByName("extractDeepLinksForAarRelease").dependsOn(buildEd25519Bip32Task) + tasks.getByName("packageReleaseResources").dependsOn(buildEd25519Bip32Task) + tasks.getByName("mergeReleaseResources").dependsOn(buildEd25519Bip32Task) if (tasks.findByName("iosX64Test") != null) { tasks.named("iosX64Test") { this.enabled = false diff --git a/apollo/src/nativeInterop/cinterop/ed25519_bip32.def b/apollo/src/nativeInterop/cinterop/ed25519_bip32.def new file mode 100644 index 000000000..36aeb1c0d --- /dev/null +++ b/apollo/src/nativeInterop/cinterop/ed25519_bip32.def @@ -0,0 +1 @@ +staticLibraries = libed25519_bip32_wrapper.a \ No newline at end of file From ff54776e56581479ccb68acd15be112529b483ae Mon Sep 17 00:00:00 2001 From: Curtish Date: Tue, 30 Apr 2024 11:05:21 +0100 Subject: [PATCH 09/39] update wasm copy dir and add basic test --- apollo/build.gradle.kts | 2 +- .../prism/apollo/derivation/EdHDKeyTest.kt | 20 +++++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) create mode 100644 apollo/src/allButJSTest/kotlin/io/iohk/atala/prism/apollo/derivation/EdHDKeyTest.kt diff --git a/apollo/build.gradle.kts b/apollo/build.gradle.kts index 594309a45..a974b8deb 100644 --- a/apollo/build.gradle.kts +++ b/apollo/build.gradle.kts @@ -297,7 +297,7 @@ val buildEd25519Bip32Wrapper by tasks.register("buildEd25519Bip32Wrapper") val copyEd25519Bip32Wasm = createCopyTask( "copyEd25519Bip32GeneratedWasm", ed25519bip32Dir.resolve("wasm").resolve("build"), - projectDir.resolve("build").resolve("js").resolve("packages").resolve("Apollo").resolve("kotlin") + rootDir.resolve("build").resolve("js").resolve("packages").resolve("Apollo").resolve("kotlin") ) copyEd25519Bip32Wasm.configure { mustRunAfter(buildEd25519Bip32Wasm) diff --git a/apollo/src/allButJSTest/kotlin/io/iohk/atala/prism/apollo/derivation/EdHDKeyTest.kt b/apollo/src/allButJSTest/kotlin/io/iohk/atala/prism/apollo/derivation/EdHDKeyTest.kt new file mode 100644 index 000000000..040311437 --- /dev/null +++ b/apollo/src/allButJSTest/kotlin/io/iohk/atala/prism/apollo/derivation/EdHDKeyTest.kt @@ -0,0 +1,20 @@ +package io.iohk.atala.prism.apollo.derivation + +import io.iohk.atala.prism.apollo.utils.decodeHex +import io.iohk.atala.prism.apollo.utils.toHexString +import kotlin.test.Test +import kotlin.test.assertEquals + +class EdHDKeyTest { + @Test + fun test_derive_m1() { + val privateKey = "f8a29231ee38d6c5bf715d5bac21c750577aa3798b22d79d65bf97d6fadea15adcd1ee1abdf78bd4be64731a12deb94d3671784112eb6f364b871851fd1c9a24".decodeHex() + val chainCode = "7384db9ad6003bbd08b3b1ddc0d07a597293ff85e961bf252b331262eddfad0d".decodeHex() + + val key = EdHDKey(privateKey, chainCode) + val derived = key.derive("m/1'") + + assertEquals(derived.privateKey.toHexString(), "4057eb6cab9000e3b6fe7e556341da1ca2f5dde0b689a7b58cb93f1902dfa15a5a10732ff348051c6e0865c62931d4a73fa8050b8ff543b43fc0000a7e2c5700") + assertEquals(derived.chainCode.toHexString(), "9a170f689c8b9b3502ee846f457ab3dd1b017cfb2cd68865c7f24dbabcbc2256") + } +} From ce6d28f915649be5ca2ad491c40defe88a7eb5dd Mon Sep 17 00:00:00 2001 From: Ahmed Moussa Date: Tue, 30 Apr 2024 15:20:00 +0400 Subject: [PATCH 10/39] fix: updating namespace in UDL to correctly map to generated binaries Signed-off-by: Ahmed Moussa --- apollo/build.gradle.kts | 71 ++++++++----------- .../atala/prism/apollo/derivation/EdHDKey.kt | 2 +- ...19_bip32.def => ed25519_bip32_wrapper.def} | 0 rust-ed25519-bip32 | 2 +- 4 files changed, 33 insertions(+), 42 deletions(-) rename apollo/src/nativeInterop/cinterop/{ed25519_bip32.def => ed25519_bip32_wrapper.def} (100%) diff --git a/apollo/build.gradle.kts b/apollo/build.gradle.kts index a974b8deb..f87cec0ec 100644 --- a/apollo/build.gradle.kts +++ b/apollo/build.gradle.kts @@ -89,7 +89,7 @@ fun KotlinNativeTarget.secp256k1CInterop(target: String) { fun KotlinNativeTarget.ed25519Bip32CInterop(target: String) { compilations.getByName("main") { cinterops { - val ed25519_bip32 by creating { + val ed25519_bip32_wrapper by creating { val crate = this.name packageName("$crate.cinterop") header( @@ -682,39 +682,6 @@ android { } } -afterEvaluate { - tasks.withType { - dependsOn( - ":iOSLibs:buildIOHKCryptoKitIphoneos", - ":iOSLibs:buildIOHKCryptoKitIphonesimulator", - ":iOSLibs:buildIOHKCryptoKitMacosx", - ":iOSLibs:buildIOHKSecureRandomGenerationIphoneos", - ":iOSLibs:buildIOHKSecureRandomGenerationIphonesimulator", - ":iOSLibs:buildIOHKSecureRandomGenerationMacosx" - ) - } - tasks.withType { - dependsOn( - ":iOSLibs:buildIOHKCryptoKitIphoneos", - ":iOSLibs:buildIOHKCryptoKitIphonesimulator", - ":iOSLibs:buildIOHKCryptoKitMacosx", - ":iOSLibs:buildIOHKSecureRandomGenerationIphoneos", - ":iOSLibs:buildIOHKSecureRandomGenerationIphonesimulator", - ":iOSLibs:buildIOHKSecureRandomGenerationMacosx" - ) - } - tasks.withType { - dependsOn( - ":iOSLibs:buildIOHKCryptoKitIphoneos", - ":iOSLibs:buildIOHKCryptoKitIphonesimulator", - ":iOSLibs:buildIOHKCryptoKitMacosx", - ":iOSLibs:buildIOHKSecureRandomGenerationIphoneos", - ":iOSLibs:buildIOHKSecureRandomGenerationIphonesimulator", - ":iOSLibs:buildIOHKSecureRandomGenerationMacosx" - ) - } -} - ktlint { filter { exclude { @@ -804,17 +771,41 @@ npmPublish { // Workaround for a bug in Gradle afterEvaluate { - tasks.getByName("clean") { - // dependsOn(cleanEd25519Bip32) + tasks.withType { + dependsOn( + ":iOSLibs:buildIOHKCryptoKitIphoneos", + ":iOSLibs:buildIOHKCryptoKitIphonesimulator", + ":iOSLibs:buildIOHKCryptoKitMacosx", + ":iOSLibs:buildIOHKSecureRandomGenerationIphoneos", + ":iOSLibs:buildIOHKSecureRandomGenerationIphonesimulator", + ":iOSLibs:buildIOHKSecureRandomGenerationMacosx", + buildEd25519Bip32Task + ) } tasks.withType { - dependsOn(buildEd25519Bip32Task) + dependsOn( + ":iOSLibs:buildIOHKCryptoKitIphoneos", + ":iOSLibs:buildIOHKCryptoKitIphonesimulator", + ":iOSLibs:buildIOHKCryptoKitMacosx", + ":iOSLibs:buildIOHKSecureRandomGenerationIphoneos", + ":iOSLibs:buildIOHKSecureRandomGenerationIphonesimulator", + ":iOSLibs:buildIOHKSecureRandomGenerationMacosx", + buildEd25519Bip32Task + ) } tasks.withType { - dependsOn(copyEd25519Bip32GeneratedTask) + dependsOn( + ":iOSLibs:buildIOHKCryptoKitIphoneos", + ":iOSLibs:buildIOHKCryptoKitIphonesimulator", + ":iOSLibs:buildIOHKCryptoKitMacosx", + ":iOSLibs:buildIOHKSecureRandomGenerationIphoneos", + ":iOSLibs:buildIOHKSecureRandomGenerationIphonesimulator", + ":iOSLibs:buildIOHKSecureRandomGenerationMacosx", + copyEd25519Bip32GeneratedTask + ) } - tasks.withType { - dependsOn(buildEd25519Bip32Task) + tasks.getByName("clean") { + // dependsOn(cleanEd25519Bip32) } tasks.withType { dependsOn(buildEd25519Bip32Task) diff --git a/apollo/src/allButJSMain/kotlin/io/iohk/atala/prism/apollo/derivation/EdHDKey.kt b/apollo/src/allButJSMain/kotlin/io/iohk/atala/prism/apollo/derivation/EdHDKey.kt index 08638bd40..166c207b9 100644 --- a/apollo/src/allButJSMain/kotlin/io/iohk/atala/prism/apollo/derivation/EdHDKey.kt +++ b/apollo/src/allButJSMain/kotlin/io/iohk/atala/prism/apollo/derivation/EdHDKey.kt @@ -1,7 +1,7 @@ package io.iohk.atala.prism.apollo.derivation import com.ionspin.kotlin.bignum.integer.toBigInteger -import ed25519_bip32.XPrvWrapper +import ed25519_bip32_wrapper.XPrvWrapper import io.iohk.atala.prism.apollo.utils.ECConfig /** diff --git a/apollo/src/nativeInterop/cinterop/ed25519_bip32.def b/apollo/src/nativeInterop/cinterop/ed25519_bip32_wrapper.def similarity index 100% rename from apollo/src/nativeInterop/cinterop/ed25519_bip32.def rename to apollo/src/nativeInterop/cinterop/ed25519_bip32_wrapper.def diff --git a/rust-ed25519-bip32 b/rust-ed25519-bip32 index 5542ef8de..dfe7ab8e2 160000 --- a/rust-ed25519-bip32 +++ b/rust-ed25519-bip32 @@ -1 +1 @@ -Subproject commit 5542ef8de79b324bbb8a060d8a8dfb08bfcfea98 +Subproject commit dfe7ab8e253ae77cbcdf0be35f3f1c8be75d0d71 From 7ef2af083d04e4a1f64c1864d554b0a576973e6b Mon Sep 17 00:00:00 2001 From: Curtish Date: Tue, 30 Apr 2024 14:53:49 +0100 Subject: [PATCH 11/39] fix: forcing ed25519 wasm into test folder --- apollo/build.gradle.kts | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/apollo/build.gradle.kts b/apollo/build.gradle.kts index f87cec0ec..9e830dddd 100644 --- a/apollo/build.gradle.kts +++ b/apollo/build.gradle.kts @@ -1,15 +1,16 @@ + import dev.petuska.npm.publish.extension.domain.NpmAccess import org.gradle.internal.os.OperatingSystem import org.jetbrains.dokka.gradle.DokkaTask +import org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi import org.jetbrains.kotlin.gradle.plugin.mpp.BitcodeEmbeddingMode import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget import org.jetbrains.kotlin.gradle.targets.js.webpack.KotlinWebpackOutput.Target import org.jetbrains.kotlin.gradle.tasks.CInteropProcess import org.jetbrains.kotlin.gradle.tasks.KotlinCompile +import org.jlleitschuh.gradle.ktlint.tasks.KtLintCheckTask import java.net.URL import java.time.Year -import org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi -import org.jlleitschuh.gradle.ktlint.tasks.KtLintCheckTask val currentModuleName: String = "Apollo" val os: OperatingSystem = OperatingSystem.current() @@ -303,6 +304,16 @@ copyEd25519Bip32Wasm.configure { mustRunAfter(buildEd25519Bip32Wasm) } +val copyEd25519Bip32WasmTest = createCopyTask( + "copyEd25519Bip32GeneratedWasmTest", + ed25519bip32Dir.resolve("wasm").resolve("build"), + rootDir.resolve("build").resolve("js").resolve("packages").resolve("Apollo-test").resolve("kotlin") +) +copyEd25519Bip32WasmTest.configure { + mustRunAfter(buildEd25519Bip32Wasm) +} + + val buildEd25519Bip32Wasm by tasks.register("buildEd25519Bip32Wasm") { group = taskGroup workingDir = ed25519bip32Dir.resolve("wasm") @@ -311,7 +322,7 @@ val buildEd25519Bip32Wasm by tasks.register("buildEd25519Bip32Wasm") { val buildEd25519Bip32Task by tasks.register("buildEd25519Bip32") { group = taskGroup - dependsOn(buildEd25519Bip32Wasm, copyEd25519Bip32Wasm, buildEd25519Bip32Wrapper, copyEd25519Bip32Wrapper) + dependsOn(buildEd25519Bip32Wasm, copyEd25519Bip32Wasm, copyEd25519Bip32WasmTest, buildEd25519Bip32Wrapper, copyEd25519Bip32Wrapper) } val cleanEd25519Bip32 by tasks.register("cleanEd25519Bip32") { @@ -468,7 +479,8 @@ kotlin { } this.testTask { this.useKarma { - this.useChromeHeadless() +// this.useChromeHeadless() + this.useFirefox() } } } From 1f3ec54119069da3c7765fb2b70f8ed82b507344 Mon Sep 17 00:00:00 2001 From: Curtish Date: Tue, 30 Apr 2024 15:04:51 +0100 Subject: [PATCH 12/39] lint --- apollo/build.gradle.kts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/apollo/build.gradle.kts b/apollo/build.gradle.kts index 9e830dddd..09e9bdb49 100644 --- a/apollo/build.gradle.kts +++ b/apollo/build.gradle.kts @@ -313,7 +313,6 @@ copyEd25519Bip32WasmTest.configure { mustRunAfter(buildEd25519Bip32Wasm) } - val buildEd25519Bip32Wasm by tasks.register("buildEd25519Bip32Wasm") { group = taskGroup workingDir = ed25519bip32Dir.resolve("wasm") @@ -479,8 +478,7 @@ kotlin { } this.testTask { this.useKarma { -// this.useChromeHeadless() - this.useFirefox() + this.useChromeHeadless() } } } From c7aac5926b19a85abef3c515625f6be5874bc66f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Francisco=20Javier=20Ribo=CC=81=20Labrador?= Date: Tue, 30 Apr 2024 16:49:16 +0200 Subject: [PATCH 13/39] =?UTF-8?q?fix:=20add=20convert=20function=20for=20K?= =?UTF-8?q?MMEdPrivate=20key=20conversion=20to=20x25519Private=20keySigned?= =?UTF-8?q?-off-by:=20Francisco=20Javier=20Rib=C3=B3=20Labrador=20?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../atala/prism/apollo/utils/KMMEdPrivateKey.kt | 10 ++++++++++ .../atala/prism/apollo/utils/KMMEdPrivateKey.kt | 10 ++++++++++ .../atala/prism/apollo/utils/ConvertEd25519.kt | 17 +++++++++++++++++ .../atala/prism/apollo/utils/KMMEdKeyPair.kt | 3 +++ .../atala/prism/apollo/utils/KMMEdPrivateKey.kt | 8 ++++++++ .../atala/prism/apollo/utils/KMMEdPrivateKey.kt | 10 ++++++++++ .../atala/prism/apollo/utils/KMMEdPrivateKey.kt | 10 ++++++++++ 7 files changed, 68 insertions(+) create mode 100644 apollo/src/commonMain/kotlin/io/iohk/atala/prism/apollo/utils/ConvertEd25519.kt diff --git a/apollo/src/androidMain/kotlin/io/iohk/atala/prism/apollo/utils/KMMEdPrivateKey.kt b/apollo/src/androidMain/kotlin/io/iohk/atala/prism/apollo/utils/KMMEdPrivateKey.kt index 8a5729ce8..60473db6e 100644 --- a/apollo/src/androidMain/kotlin/io/iohk/atala/prism/apollo/utils/KMMEdPrivateKey.kt +++ b/apollo/src/androidMain/kotlin/io/iohk/atala/prism/apollo/utils/KMMEdPrivateKey.kt @@ -33,4 +33,14 @@ actual class KMMEdPrivateKey(val raw: ByteArray) { signer.update(message, 0, message.size) return signer.generateSignature() } + + /** + * Method convert an ed25519 private key to a x25519 private key + * + * @return KMMX25519PrivateKey private key + */ + actual fun x25519PrivateKey(): KMMX25519PrivateKey { + val rawX25519Prv = convertSecretKeyToX25519(this.raw) + return KMMX25519PrivateKey(rawX25519Prv) + } } diff --git a/apollo/src/appleMain/kotlin/io/iohk/atala/prism/apollo/utils/KMMEdPrivateKey.kt b/apollo/src/appleMain/kotlin/io/iohk/atala/prism/apollo/utils/KMMEdPrivateKey.kt index b6361ee6a..6ffb1031b 100644 --- a/apollo/src/appleMain/kotlin/io/iohk/atala/prism/apollo/utils/KMMEdPrivateKey.kt +++ b/apollo/src/appleMain/kotlin/io/iohk/atala/prism/apollo/utils/KMMEdPrivateKey.kt @@ -44,4 +44,14 @@ public actual class KMMEdPrivateKey(val raw: ByteArray) { val publicRaw = result.success()?.toByteArray() ?: throw RuntimeException("Null result") return KMMEdPublicKey(publicRaw) } + + /** + * Method convert an ed25519 private key to a x25519 private key + * + * @return KMMX25519PrivateKey private key + */ + actual fun x25519PrivateKey(): KMMX25519PrivateKey { + val rawX25519Prv = convertSecretKeyToX25519(this.raw) + return KMMX25519PrivateKey(rawX25519Prv) + } } diff --git a/apollo/src/commonMain/kotlin/io/iohk/atala/prism/apollo/utils/ConvertEd25519.kt b/apollo/src/commonMain/kotlin/io/iohk/atala/prism/apollo/utils/ConvertEd25519.kt new file mode 100644 index 000000000..cecee8a2e --- /dev/null +++ b/apollo/src/commonMain/kotlin/io/iohk/atala/prism/apollo/utils/ConvertEd25519.kt @@ -0,0 +1,17 @@ +package io.iohk.atala.prism.apollo.utils + +import org.kotlincrypto.hash.sha2.SHA512 +import kotlin.experimental.and +import kotlin.experimental.or + + +fun convertSecretKeyToX25519(secretKey: ByteArray): ByteArray { + // Hash the first 32 bytes of the Ed25519 secret key + val hashed = SHA512().digest(secretKey.sliceArray(0 until 32)) + // Clamping the hashed value to conform with X25519 format + hashed[0] = hashed[0] and 248.toByte() + hashed[31] = hashed[31] and 127.toByte() + hashed[31] = hashed[31] or 64.toByte() + // Return the first 32 bytes of the hash as the X25519 secret key + return hashed.sliceArray(0 until 32) +} \ No newline at end of file diff --git a/apollo/src/commonMain/kotlin/io/iohk/atala/prism/apollo/utils/KMMEdKeyPair.kt b/apollo/src/commonMain/kotlin/io/iohk/atala/prism/apollo/utils/KMMEdKeyPair.kt index d534ad53d..cb8f649fb 100644 --- a/apollo/src/commonMain/kotlin/io/iohk/atala/prism/apollo/utils/KMMEdKeyPair.kt +++ b/apollo/src/commonMain/kotlin/io/iohk/atala/prism/apollo/utils/KMMEdKeyPair.kt @@ -1,5 +1,7 @@ package io.iohk.atala.prism.apollo.utils +import kotlin.js.ExperimentalJsExport + /** * Interface defining the functionality for generating KMMEd key pairs. */ @@ -7,6 +9,7 @@ expect class KMMEdKeyPair(privateKey: KMMEdPrivateKey, publicKey: KMMEdPublicKey val privateKey: KMMEdPrivateKey val publicKey: KMMEdPublicKey + @OptIn(ExperimentalJsExport::class) companion object : Ed25519KeyPairGeneration /** diff --git a/apollo/src/commonMain/kotlin/io/iohk/atala/prism/apollo/utils/KMMEdPrivateKey.kt b/apollo/src/commonMain/kotlin/io/iohk/atala/prism/apollo/utils/KMMEdPrivateKey.kt index f4c61fc87..820d00424 100644 --- a/apollo/src/commonMain/kotlin/io/iohk/atala/prism/apollo/utils/KMMEdPrivateKey.kt +++ b/apollo/src/commonMain/kotlin/io/iohk/atala/prism/apollo/utils/KMMEdPrivateKey.kt @@ -12,4 +12,12 @@ public expect class KMMEdPrivateKey { * @return ByteArray representing the signed message */ fun sign(message: ByteArray): ByteArray + + /** + * Method convert an ed25519 private key to a x25519 private key + * + * @return KMMX25519PrivateKey private key + */ + fun x25519PrivateKey(): KMMX25519PrivateKey + } diff --git a/apollo/src/jsMain/kotlin/io/iohk/atala/prism/apollo/utils/KMMEdPrivateKey.kt b/apollo/src/jsMain/kotlin/io/iohk/atala/prism/apollo/utils/KMMEdPrivateKey.kt index 35f4b3584..90afe0546 100644 --- a/apollo/src/jsMain/kotlin/io/iohk/atala/prism/apollo/utils/KMMEdPrivateKey.kt +++ b/apollo/src/jsMain/kotlin/io/iohk/atala/prism/apollo/utils/KMMEdPrivateKey.kt @@ -51,4 +51,14 @@ actual class KMMEdPrivateKey(bytes: ByteArray) { return sig.toHex().encodeToByteArray() } + + /** + * Method convert an ed25519 private key to a x25519 private key + * + * @return KMMX25519PrivateKey private key + */ + actual fun x25519PrivateKey(): KMMX25519PrivateKey { + val rawX25519Prv = convertSecretKeyToX25519(this.raw.toByteArray()) + return KMMX25519PrivateKey(rawX25519Prv) + } } diff --git a/apollo/src/jvmMain/kotlin/io/iohk/atala/prism/apollo/utils/KMMEdPrivateKey.kt b/apollo/src/jvmMain/kotlin/io/iohk/atala/prism/apollo/utils/KMMEdPrivateKey.kt index 6c2d48b26..6cfd35125 100644 --- a/apollo/src/jvmMain/kotlin/io/iohk/atala/prism/apollo/utils/KMMEdPrivateKey.kt +++ b/apollo/src/jvmMain/kotlin/io/iohk/atala/prism/apollo/utils/KMMEdPrivateKey.kt @@ -34,4 +34,14 @@ actual class KMMEdPrivateKey(val raw: ByteArray) { signer.update(message, 0, message.size) return signer.generateSignature() } + + /** + * Method convert an ed25519 private key to a x25519 private key + * + * @return KMMX25519PrivateKey private key + */ + actual fun x25519PrivateKey(): KMMX25519PrivateKey { + val rawX25519Prv = convertSecretKeyToX25519(this.raw) + return KMMX25519PrivateKey(rawX25519Prv) + } } From e17fb3cebb98908d59873babcbead5a30dd7a472 Mon Sep 17 00:00:00 2001 From: Curtish Date: Fri, 3 May 2024 09:36:22 +0100 Subject: [PATCH 14/39] fix: JS wrap EdHdKey.initFromSeed in companion to make static Signed-off-by: Curtis Harding --- .../prism/apollo/utils/ConvertEd25519.kt | 3 +- .../prism/apollo/utils/KMMEdPrivateKey.kt | 1 - .../atala/prism/apollo/derivation/EdHDKey.kt | 36 ++++++++++--------- .../prism/apollo/utils/Curve25519Parser.kt | 7 ++++ 4 files changed, 27 insertions(+), 20 deletions(-) diff --git a/apollo/src/commonMain/kotlin/io/iohk/atala/prism/apollo/utils/ConvertEd25519.kt b/apollo/src/commonMain/kotlin/io/iohk/atala/prism/apollo/utils/ConvertEd25519.kt index cecee8a2e..ff315dcd3 100644 --- a/apollo/src/commonMain/kotlin/io/iohk/atala/prism/apollo/utils/ConvertEd25519.kt +++ b/apollo/src/commonMain/kotlin/io/iohk/atala/prism/apollo/utils/ConvertEd25519.kt @@ -4,7 +4,6 @@ import org.kotlincrypto.hash.sha2.SHA512 import kotlin.experimental.and import kotlin.experimental.or - fun convertSecretKeyToX25519(secretKey: ByteArray): ByteArray { // Hash the first 32 bytes of the Ed25519 secret key val hashed = SHA512().digest(secretKey.sliceArray(0 until 32)) @@ -14,4 +13,4 @@ fun convertSecretKeyToX25519(secretKey: ByteArray): ByteArray { hashed[31] = hashed[31] or 64.toByte() // Return the first 32 bytes of the hash as the X25519 secret key return hashed.sliceArray(0 until 32) -} \ No newline at end of file +} diff --git a/apollo/src/commonMain/kotlin/io/iohk/atala/prism/apollo/utils/KMMEdPrivateKey.kt b/apollo/src/commonMain/kotlin/io/iohk/atala/prism/apollo/utils/KMMEdPrivateKey.kt index 820d00424..b063b4b78 100644 --- a/apollo/src/commonMain/kotlin/io/iohk/atala/prism/apollo/utils/KMMEdPrivateKey.kt +++ b/apollo/src/commonMain/kotlin/io/iohk/atala/prism/apollo/utils/KMMEdPrivateKey.kt @@ -19,5 +19,4 @@ public expect class KMMEdPrivateKey { * @return KMMX25519PrivateKey private key */ fun x25519PrivateKey(): KMMX25519PrivateKey - } diff --git a/apollo/src/jsMain/kotlin/io/iohk/atala/prism/apollo/derivation/EdHDKey.kt b/apollo/src/jsMain/kotlin/io/iohk/atala/prism/apollo/derivation/EdHDKey.kt index 1b7894eaf..4ac9dd538 100644 --- a/apollo/src/jsMain/kotlin/io/iohk/atala/prism/apollo/derivation/EdHDKey.kt +++ b/apollo/src/jsMain/kotlin/io/iohk/atala/prism/apollo/derivation/EdHDKey.kt @@ -16,25 +16,27 @@ class EdHDKey( val depth: Int = 0, val index: BigIntegerWrapper = BigIntegerWrapper(0) ) { - /** - * Constructs a new EdHDKey object from a seed - * - * @param seed The seed used to derive the private key and chain code. - * @throws IllegalArgumentException if the seed length is not equal to 64. - */ - fun initFromSeed(seed: ByteArray): EdHDKey { - require(seed.size == 64) { - "Seed expected byte length to be ${ECConfig.PRIVATE_KEY_BYTE_SIZE}" - } + companion object { + /** + * Constructs a new EdHDKey object from a seed + * + * @param seed The seed used to derive the private key and chain code. + * @throws IllegalArgumentException if the seed length is not equal to 64. + */ + fun initFromSeed(seed: ByteArray): EdHDKey { + require(seed.size == 64) { + "Seed expected byte length to be ${ECConfig.PRIVATE_KEY_BYTE_SIZE}" + } - val key = seed.sliceArray(0 until 32) - val chainCode = seed.sliceArray(32 until seed.size) - val wrapper = ed25519_bip32.XPrvWrapper.from_nonextended_noforce(key, chainCode) + val key = seed.sliceArray(0 until 32) + val chainCode = seed.sliceArray(32 until seed.size) + val wrapper = ed25519_bip32.XPrvWrapper.from_nonextended_noforce(key, chainCode) - return EdHDKey( - privateKey = wrapper.extended_secret_key(), - chainCode = wrapper.chain_code() - ) + return EdHDKey( + privateKey = wrapper.extended_secret_key(), + chainCode = wrapper.chain_code() + ) + } } /** diff --git a/apollo/src/jsMain/kotlin/io/iohk/atala/prism/apollo/utils/Curve25519Parser.kt b/apollo/src/jsMain/kotlin/io/iohk/atala/prism/apollo/utils/Curve25519Parser.kt index adb746576..b7ca8405f 100644 --- a/apollo/src/jsMain/kotlin/io/iohk/atala/prism/apollo/utils/Curve25519Parser.kt +++ b/apollo/src/jsMain/kotlin/io/iohk/atala/prism/apollo/utils/Curve25519Parser.kt @@ -1,6 +1,8 @@ package io.iohk.atala.prism.apollo.utils import io.iohk.atala.prism.apollo.base64.base64UrlDecodedBytes +import io.iohk.atala.prism.apollo.utils.Curve25519Parser.encodedLength +import io.iohk.atala.prism.apollo.utils.Curve25519Parser.rawLength import node.buffer.Buffer /** @@ -13,6 +15,7 @@ import node.buffer.Buffer @OptIn(ExperimentalJsExport::class) @JsExport object Curve25519Parser { + val extendedLength = 64 val encodedLength = 43 val rawLength = 32 @@ -29,6 +32,10 @@ object Curve25519Parser { return Buffer.from(buffer.toByteArray().decodeToString().base64UrlDecodedBytes) } + if (buffer.length == extendedLength) { + return buffer + } + if (buffer.length == rawLength) { return buffer } From f28f0d96ee78a6699915f5d5cc4112b11ede0de8 Mon Sep 17 00:00:00 2001 From: Curtish Date: Fri, 3 May 2024 11:32:09 +0100 Subject: [PATCH 15/39] adding rust toolchain to workflows Signed-off-by: Curtis Harding --- .github/workflows/pull-request.yml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml index 8b26ff656..87406e0ac 100644 --- a/.github/workflows/pull-request.yml +++ b/.github/workflows/pull-request.yml @@ -63,6 +63,20 @@ jobs: with: xcode-version: '15.0.1' + - name: "Install rust toolchain" + uses: actions-rs/toolchain@v1 + with: + profile: minimal + toolchain: stable + override: true + + - name: "Install wasm-pack" + uses: actions-rs/cargo@v1 + with: + command: install + args: wasm-pack + + - name: "Test Kotlin code is properly formatted" run: ./gradlew ktlintCheck From a5c15e78d9ed19c0766c24fcb72557539a2c0903 Mon Sep 17 00:00:00 2001 From: Curtish Date: Fri, 3 May 2024 11:48:17 +0100 Subject: [PATCH 16/39] edit workflow to not use actions Signed-off-by: Curtis Harding --- .github/workflows/pull-request.yml | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml index 87406e0ac..0a3118765 100644 --- a/.github/workflows/pull-request.yml +++ b/.github/workflows/pull-request.yml @@ -63,20 +63,17 @@ jobs: with: xcode-version: '15.0.1' - - name: "Install rust toolchain" - uses: actions-rs/toolchain@v1 - with: - profile: minimal - toolchain: stable - override: true + - name: "Install rust toolchain (Linux)" + if: matrix.os-type == 'linux' + run: sudo apt install rustc -y + + - name: "Install rust toolchain (Macos)" + if: matrix.os-type == 'macos' + run: brew install rustup - name: "Install wasm-pack" - uses: actions-rs/cargo@v1 - with: - command: install - args: wasm-pack + run: cargo install wasm-pack - - name: "Test Kotlin code is properly formatted" run: ./gradlew ktlintCheck From f40bfdbb4fb17f7a0385075bbb69b810e257aa78 Mon Sep 17 00:00:00 2001 From: Curtish Date: Fri, 3 May 2024 13:19:41 +0100 Subject: [PATCH 17/39] rust-ed25519-bip32 submodule update Signed-off-by: Curtis Harding --- rust-ed25519-bip32 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-ed25519-bip32 b/rust-ed25519-bip32 index dfe7ab8e2..156c3dae7 160000 --- a/rust-ed25519-bip32 +++ b/rust-ed25519-bip32 @@ -1 +1 @@ -Subproject commit dfe7ab8e253ae77cbcdf0be35f3f1c8be75d0d71 +Subproject commit 156c3dae7309ef27c70f537185fe30358fd64208 From b68627095f4e2b9ce190719fbe7fc8ce6294f120 Mon Sep 17 00:00:00 2001 From: Ahmed Moussa Date: Mon, 6 May 2024 15:52:13 +0400 Subject: [PATCH 18/39] chore: rust-ed25519-bip32 submodule update Signed-off-by: Ahmed Moussa --- rust-ed25519-bip32 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-ed25519-bip32 b/rust-ed25519-bip32 index 156c3dae7..02c27946f 160000 --- a/rust-ed25519-bip32 +++ b/rust-ed25519-bip32 @@ -1 +1 @@ -Subproject commit 156c3dae7309ef27c70f537185fe30358fd64208 +Subproject commit 02c27946fa8d023c4bfe962d4209d513a44df629 From 3d2e13691493ceffd9c797dcffe80bbae7ee18d3 Mon Sep 17 00:00:00 2001 From: Ahmed Moussa Date: Mon, 6 May 2024 15:55:14 +0400 Subject: [PATCH 19/39] chore: rust-ed25519-bip32 submodule update Signed-off-by: Ahmed Moussa --- rust-ed25519-bip32 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-ed25519-bip32 b/rust-ed25519-bip32 index 02c27946f..e5487b0b1 160000 --- a/rust-ed25519-bip32 +++ b/rust-ed25519-bip32 @@ -1 +1 @@ -Subproject commit 02c27946fa8d023c4bfe962d4209d513a44df629 +Subproject commit e5487b0b1a42672fce33779aef52f57eec87454a From f67452bb485338bc0bee0c3bd5a419603e1c3d97 Mon Sep 17 00:00:00 2001 From: Ahmed Moussa Date: Mon, 6 May 2024 17:27:07 +0400 Subject: [PATCH 20/39] chore: rust-ed25519-bip32 submodule update Signed-off-by: Ahmed Moussa --- apollo/build.gradle.kts | 7 ++++--- .../io/iohk/atala/prism/apollo/derivation/EdHDKeyTest.kt | 2 ++ .../io/iohk/atala/prism/apollo/IgnoreAndroid.android.kt | 6 ++++++ .../kotlin/io/iohk/atala/prism/apollo/IgnoreAndroid.kt | 6 ++++++ .../kotlin/io/iohk/atala/prism/apollo/IgnoreAndroid.js.kt | 6 ++++++ .../kotlin/io/iohk/atala/prism/apollo/IgnoreAndroid.jvm.kt | 6 ++++++ .../io/iohk/atala/prism/apollo/IgnoreAndroid.native.kt | 6 ++++++ apollo/webpack.config.d/polyfill.js | 3 ++- rust-ed25519-bip32 | 2 +- 9 files changed, 39 insertions(+), 5 deletions(-) create mode 100644 apollo/src/androidUnitTest/kotlin/io/iohk/atala/prism/apollo/IgnoreAndroid.android.kt create mode 100644 apollo/src/commonTest/kotlin/io/iohk/atala/prism/apollo/IgnoreAndroid.kt create mode 100644 apollo/src/jsTest/kotlin/io/iohk/atala/prism/apollo/IgnoreAndroid.js.kt create mode 100644 apollo/src/jvmTest/kotlin/io/iohk/atala/prism/apollo/IgnoreAndroid.jvm.kt create mode 100644 apollo/src/nativeTest/kotlin/io/iohk/atala/prism/apollo/IgnoreAndroid.native.kt diff --git a/apollo/build.gradle.kts b/apollo/build.gradle.kts index 09e9bdb49..5c7017235 100644 --- a/apollo/build.gradle.kts +++ b/apollo/build.gradle.kts @@ -1,4 +1,3 @@ - import dev.petuska.npm.publish.extension.domain.NpmAccess import org.gradle.internal.os.OperatingSystem import org.jetbrains.dokka.gradle.DokkaTask @@ -821,12 +820,14 @@ afterEvaluate { dependsOn(buildEd25519Bip32Task) } tasks.getByName("mergeDebugJniLibFolders").dependsOn(buildEd25519Bip32Task) + tasks.getByName("mergeReleaseJniLibFolders").dependsOn(buildEd25519Bip32Task) tasks.getByName("packageDebugResources").dependsOn(buildEd25519Bip32Task) + tasks.getByName("packageReleaseResources").dependsOn(buildEd25519Bip32Task) tasks.getByName("extractDeepLinksForAarDebug").dependsOn(buildEd25519Bip32Task) - tasks.getByName("mergeReleaseJniLibFolders").dependsOn(buildEd25519Bip32Task) tasks.getByName("extractDeepLinksForAarRelease").dependsOn(buildEd25519Bip32Task) - tasks.getByName("packageReleaseResources").dependsOn(buildEd25519Bip32Task) + tasks.getByName("mergeDebugResources").dependsOn(buildEd25519Bip32Task) tasks.getByName("mergeReleaseResources").dependsOn(buildEd25519Bip32Task) + if (tasks.findByName("iosX64Test") != null) { tasks.named("iosX64Test") { this.enabled = false diff --git a/apollo/src/allButJSTest/kotlin/io/iohk/atala/prism/apollo/derivation/EdHDKeyTest.kt b/apollo/src/allButJSTest/kotlin/io/iohk/atala/prism/apollo/derivation/EdHDKeyTest.kt index 040311437..67f38fb87 100644 --- a/apollo/src/allButJSTest/kotlin/io/iohk/atala/prism/apollo/derivation/EdHDKeyTest.kt +++ b/apollo/src/allButJSTest/kotlin/io/iohk/atala/prism/apollo/derivation/EdHDKeyTest.kt @@ -1,10 +1,12 @@ package io.iohk.atala.prism.apollo.derivation +import io.iohk.atala.prism.apollo.IgnoreAndroid import io.iohk.atala.prism.apollo.utils.decodeHex import io.iohk.atala.prism.apollo.utils.toHexString import kotlin.test.Test import kotlin.test.assertEquals +@IgnoreAndroid class EdHDKeyTest { @Test fun test_derive_m1() { diff --git a/apollo/src/androidUnitTest/kotlin/io/iohk/atala/prism/apollo/IgnoreAndroid.android.kt b/apollo/src/androidUnitTest/kotlin/io/iohk/atala/prism/apollo/IgnoreAndroid.android.kt new file mode 100644 index 000000000..166442dd8 --- /dev/null +++ b/apollo/src/androidUnitTest/kotlin/io/iohk/atala/prism/apollo/IgnoreAndroid.android.kt @@ -0,0 +1,6 @@ +package io.iohk.atala.prism.apollo + +/** + * Ignore unit tests in Android Target + */ +actual typealias IgnoreAndroid = org.junit.Ignore diff --git a/apollo/src/commonTest/kotlin/io/iohk/atala/prism/apollo/IgnoreAndroid.kt b/apollo/src/commonTest/kotlin/io/iohk/atala/prism/apollo/IgnoreAndroid.kt new file mode 100644 index 000000000..d2de0535b --- /dev/null +++ b/apollo/src/commonTest/kotlin/io/iohk/atala/prism/apollo/IgnoreAndroid.kt @@ -0,0 +1,6 @@ +package io.iohk.atala.prism.apollo + +/** + * Ignore unit tests in Android Target + */ +expect annotation class IgnoreAndroid() diff --git a/apollo/src/jsTest/kotlin/io/iohk/atala/prism/apollo/IgnoreAndroid.js.kt b/apollo/src/jsTest/kotlin/io/iohk/atala/prism/apollo/IgnoreAndroid.js.kt new file mode 100644 index 000000000..3317eb5d4 --- /dev/null +++ b/apollo/src/jsTest/kotlin/io/iohk/atala/prism/apollo/IgnoreAndroid.js.kt @@ -0,0 +1,6 @@ +package io.iohk.atala.prism.apollo + +/** + * Ignore unit tests in Android Target + */ +actual annotation class IgnoreAndroid diff --git a/apollo/src/jvmTest/kotlin/io/iohk/atala/prism/apollo/IgnoreAndroid.jvm.kt b/apollo/src/jvmTest/kotlin/io/iohk/atala/prism/apollo/IgnoreAndroid.jvm.kt new file mode 100644 index 000000000..3317eb5d4 --- /dev/null +++ b/apollo/src/jvmTest/kotlin/io/iohk/atala/prism/apollo/IgnoreAndroid.jvm.kt @@ -0,0 +1,6 @@ +package io.iohk.atala.prism.apollo + +/** + * Ignore unit tests in Android Target + */ +actual annotation class IgnoreAndroid diff --git a/apollo/src/nativeTest/kotlin/io/iohk/atala/prism/apollo/IgnoreAndroid.native.kt b/apollo/src/nativeTest/kotlin/io/iohk/atala/prism/apollo/IgnoreAndroid.native.kt new file mode 100644 index 000000000..3317eb5d4 --- /dev/null +++ b/apollo/src/nativeTest/kotlin/io/iohk/atala/prism/apollo/IgnoreAndroid.native.kt @@ -0,0 +1,6 @@ +package io.iohk.atala.prism.apollo + +/** + * Ignore unit tests in Android Target + */ +actual annotation class IgnoreAndroid diff --git a/apollo/webpack.config.d/polyfill.js b/apollo/webpack.config.d/polyfill.js index f5b3bf1c8..1c40c5b92 100644 --- a/apollo/webpack.config.d/polyfill.js +++ b/apollo/webpack.config.d/polyfill.js @@ -1,6 +1,7 @@ config.resolve = { fallback: { - stream: require.resolve("stream-browserify") + stream: require.resolve("stream-browserify"), + "url": require.resolve("url/") } }; var webpack = require('webpack'); diff --git a/rust-ed25519-bip32 b/rust-ed25519-bip32 index e5487b0b1..f8d97b2bf 160000 --- a/rust-ed25519-bip32 +++ b/rust-ed25519-bip32 @@ -1 +1 @@ -Subproject commit e5487b0b1a42672fce33779aef52f57eec87454a +Subproject commit f8d97b2bf4e77fcc07fe49843f0597c6a83be06b From 506d26234468154436ecd805da4a18bf031d0a46 Mon Sep 17 00:00:00 2001 From: Ahmed Moussa Date: Mon, 6 May 2024 18:39:59 +0400 Subject: [PATCH 21/39] chore: update Gradle & Kotlin file paths Signed-off-by: Ahmed Moussa --- apollo/build.gradle.kts | 54 ++++++++---- .../prism/apollo/derivation/EdHDKeyTest.kt | 22 ----- .../atala/prism/apollo/derivation/EdHDKey.kt | 62 ++++++------- .../prism/apollo/IgnoreAndroid.android.kt | 6 -- .../atala/prism/apollo/derivation/EdHDKey.kt | 88 +++++++++++++++++++ .../atala/prism/apollo/derivation/EdHDKey.kt | 42 +++++++++ .../iohk/atala/prism/apollo/IgnoreAndroid.kt | 6 -- .../prism/apollo/derivation/EdHDKeyTest.kt | 23 +++++ .../atala/prism/apollo/derivation/EdHDKey.kt | 64 +++++++------- .../atala/prism/apollo/IgnoreAndroid.js.kt | 6 -- .../atala/prism/apollo/derivation/EdHDKey.kt | 88 +++++++++++++++++++ .../atala/prism/apollo/IgnoreAndroid.jvm.kt | 6 -- .../prism/apollo/IgnoreAndroid.native.kt | 6 -- build.gradle.kts | 2 +- 14 files changed, 341 insertions(+), 134 deletions(-) delete mode 100644 apollo/src/allButJSTest/kotlin/io/iohk/atala/prism/apollo/derivation/EdHDKeyTest.kt rename apollo/src/{allButJSMain => androidMain}/kotlin/io/iohk/atala/prism/apollo/derivation/EdHDKey.kt (57%) delete mode 100644 apollo/src/androidUnitTest/kotlin/io/iohk/atala/prism/apollo/IgnoreAndroid.android.kt create mode 100644 apollo/src/appleMain/kotlin/io/iohk/atala/prism/apollo/derivation/EdHDKey.kt create mode 100644 apollo/src/commonMain/kotlin/io/iohk/atala/prism/apollo/derivation/EdHDKey.kt delete mode 100644 apollo/src/commonTest/kotlin/io/iohk/atala/prism/apollo/IgnoreAndroid.kt create mode 100644 apollo/src/commonTest/kotlin/io/iohk/atala/prism/apollo/derivation/EdHDKeyTest.kt delete mode 100644 apollo/src/jsTest/kotlin/io/iohk/atala/prism/apollo/IgnoreAndroid.js.kt create mode 100644 apollo/src/jvmMain/kotlin/io/iohk/atala/prism/apollo/derivation/EdHDKey.kt delete mode 100644 apollo/src/jvmTest/kotlin/io/iohk/atala/prism/apollo/IgnoreAndroid.jvm.kt delete mode 100644 apollo/src/nativeTest/kotlin/io/iohk/atala/prism/apollo/IgnoreAndroid.native.kt diff --git a/apollo/build.gradle.kts b/apollo/build.gradle.kts index 5c7017235..d563be138 100644 --- a/apollo/build.gradle.kts +++ b/apollo/build.gradle.kts @@ -18,8 +18,8 @@ val secp256k1Dir = rootDir.resolve("secp256k1-kmp") val taskGroup = "build ed25519-bip32" val ed25519bip32Dir = rootDir.resolve("rust-ed25519-bip32") val generatedDir = project.layout.buildDirectory.asFile.get().resolve("generated") -val sourceDir = ed25519bip32Dir.resolve("wrapper").resolve("target") -val generatedResourcesDir = projectDir.resolve("build").resolve("generatedResources") +val generatedResourcesDir = project.layout.buildDirectory.asFile.get().resolve("generatedResources") +val ed25519bip32BinariesDir = ed25519bip32Dir.resolve("wrapper").resolve("target") plugins { kotlin("multiplatform") @@ -208,12 +208,18 @@ val javadocJar by tasks.registering(Jar::class) { from(tasks.dokkaHtml) } +/** + * Copy Generated Kotlin Code + */ val copyEd25519Bip32GeneratedTask = createCopyTask( "copyEd25519Bip32Generated", ed25519bip32Dir.resolve("wrapper").resolve("build").resolve("generated"), generatedDir ) +/** + * Copy JVM Code to Android folder + */ val copyToAndroidSrc by tasks.register("copyToAndroidSrc") { group = taskGroup duplicatesStrategy = DuplicatesStrategy.INCLUDE @@ -226,63 +232,73 @@ val copyToAndroidSrc by tasks.register("copyToAndroidSrc") { val copyEd25519Bip32ForMacOSX8664Task = createCopyTask( "copyEd25519Bip32ForMacOSX86_64", - sourceDir.resolve("x86_64-apple-darwin").resolve("release"), + ed25519bip32BinariesDir.resolve("x86_64-apple-darwin").resolve("release"), generatedResourcesDir.resolve("jvm").resolve("main").resolve("darwin-x86-64") ) val copyEd25519Bip32ForMacOSArch64Task = createCopyTask( "copyEd25519Bip32ForMacOSArch64", - sourceDir.resolve("aarch64-apple-darwin").resolve("release"), + ed25519bip32BinariesDir.resolve("aarch64-apple-darwin").resolve("release"), generatedResourcesDir.resolve("jvm").resolve("main").resolve("darwin-aarch64") ) val copyEd25519Bip32ForLinuxX8664Task = createCopyTask( "copyEd25519Bip32ForLinuxX86_64", - sourceDir.resolve("x86_64-unknown-linux-gnu").resolve("release"), + ed25519bip32BinariesDir.resolve("x86_64-unknown-linux-gnu").resolve("release"), generatedResourcesDir.resolve("jvm").resolve("main").resolve("linux-x86-64") ) val copyEd25519Bip32ForLinuxArch64Task = createCopyTask( "copyEd25519Bip32ForLinuxArch64", - sourceDir.resolve("aarch64-unknown-linux-gnu").resolve("release"), + ed25519bip32BinariesDir.resolve("aarch64-unknown-linux-gnu").resolve("release"), generatedResourcesDir.resolve("jvm").resolve("main").resolve("linux-aarch64") ) +/** + * A task group that responsible for moving generated JVM binaries to correct folder. + */ +val copyEd25519Bip32ForJVMTargetTask by tasks.register("copyEd25519Bip32ForJVMTarget") { + group = taskGroup + dependsOn(copyEd25519Bip32ForMacOSX8664Task, copyEd25519Bip32ForMacOSArch64Task, copyEd25519Bip32ForLinuxX8664Task, copyEd25519Bip32ForLinuxArch64Task) +} + val copyEd25519Bip32ForAndroidX8664Task = createCopyTask( "copyEd25519Bip32ForAndroidX86_64", - sourceDir.resolve("x86_64-linux-android").resolve("release"), + ed25519bip32BinariesDir.resolve("x86_64-linux-android").resolve("release"), generatedResourcesDir.resolve("android").resolve("main").resolve("jniLibs").resolve("x86_64") ) val copyEd25519Bip32ForAndroidArch64Task = createCopyTask( "copyEd25519Bip32ForAndroidArch64", - sourceDir.resolve("aarch64-linux-android").resolve("release"), + ed25519bip32BinariesDir.resolve("aarch64-linux-android").resolve("release"), generatedResourcesDir.resolve("android").resolve("main").resolve("jniLibs").resolve("arm64-v8a") ) val copyEd25519Bip32ForAndroidI686Task = createCopyTask( "copyEd25519Bip32ForAndroidI686", - sourceDir.resolve("i686-linux-android").resolve("release"), + ed25519bip32BinariesDir.resolve("i686-linux-android").resolve("release"), generatedResourcesDir.resolve("android").resolve("main").resolve("jniLibs").resolve("x86") ) val copyEd25519Bip32ForAndroidArmv7aTask = createCopyTask( "copyEd25519Bip32ForAndroidArmv7a", - sourceDir.resolve("armv7-linux-androideabi").resolve("release"), + ed25519bip32BinariesDir.resolve("armv7-linux-androideabi").resolve("release"), generatedResourcesDir.resolve("android").resolve("main").resolve("jniLibs").resolve("armeabi-v7a") ) +/** + * A task group that responsible for moving generated Android binaries to correct folder. + */ +val copyEd25519Bip32ForAndroidTargetTask by tasks.register("copyEd25519Bip32ForAndroidTarget") { + group = taskGroup + dependsOn(copyEd25519Bip32ForAndroidX8664Task, copyEd25519Bip32ForAndroidArch64Task, copyEd25519Bip32ForAndroidI686Task, copyEd25519Bip32ForAndroidArmv7aTask) +} + val copyEd25519Bip32Wrapper by tasks.register("copyEd25519Bip32") { dependsOn( copyEd25519Bip32GeneratedTask, - copyEd25519Bip32ForMacOSX8664Task, - copyEd25519Bip32ForMacOSArch64Task, - copyEd25519Bip32ForLinuxX8664Task, - copyEd25519Bip32ForLinuxArch64Task, - copyEd25519Bip32ForAndroidX8664Task, - copyEd25519Bip32ForAndroidArch64Task, - copyEd25519Bip32ForAndroidI686Task, - copyEd25519Bip32ForAndroidArmv7aTask, + copyEd25519Bip32ForJVMTargetTask, + copyEd25519Bip32ForAndroidTargetTask, copyToAndroidSrc ) mustRunAfter(buildEd25519Bip32Wrapper) @@ -817,7 +833,7 @@ afterEvaluate { // dependsOn(cleanEd25519Bip32) } tasks.withType { - dependsOn(buildEd25519Bip32Task) + // dependsOn(buildEd25519Bip32Task) } tasks.getByName("mergeDebugJniLibFolders").dependsOn(buildEd25519Bip32Task) tasks.getByName("mergeReleaseJniLibFolders").dependsOn(buildEd25519Bip32Task) diff --git a/apollo/src/allButJSTest/kotlin/io/iohk/atala/prism/apollo/derivation/EdHDKeyTest.kt b/apollo/src/allButJSTest/kotlin/io/iohk/atala/prism/apollo/derivation/EdHDKeyTest.kt deleted file mode 100644 index 67f38fb87..000000000 --- a/apollo/src/allButJSTest/kotlin/io/iohk/atala/prism/apollo/derivation/EdHDKeyTest.kt +++ /dev/null @@ -1,22 +0,0 @@ -package io.iohk.atala.prism.apollo.derivation - -import io.iohk.atala.prism.apollo.IgnoreAndroid -import io.iohk.atala.prism.apollo.utils.decodeHex -import io.iohk.atala.prism.apollo.utils.toHexString -import kotlin.test.Test -import kotlin.test.assertEquals - -@IgnoreAndroid -class EdHDKeyTest { - @Test - fun test_derive_m1() { - val privateKey = "f8a29231ee38d6c5bf715d5bac21c750577aa3798b22d79d65bf97d6fadea15adcd1ee1abdf78bd4be64731a12deb94d3671784112eb6f364b871851fd1c9a24".decodeHex() - val chainCode = "7384db9ad6003bbd08b3b1ddc0d07a597293ff85e961bf252b331262eddfad0d".decodeHex() - - val key = EdHDKey(privateKey, chainCode) - val derived = key.derive("m/1'") - - assertEquals(derived.privateKey.toHexString(), "4057eb6cab9000e3b6fe7e556341da1ca2f5dde0b689a7b58cb93f1902dfa15a5a10732ff348051c6e0865c62931d4a73fa8050b8ff543b43fc0000a7e2c5700") - assertEquals(derived.chainCode.toHexString(), "9a170f689c8b9b3502ee846f457ab3dd1b017cfb2cd68865c7f24dbabcbc2256") - } -} diff --git a/apollo/src/allButJSMain/kotlin/io/iohk/atala/prism/apollo/derivation/EdHDKey.kt b/apollo/src/androidMain/kotlin/io/iohk/atala/prism/apollo/derivation/EdHDKey.kt similarity index 57% rename from apollo/src/allButJSMain/kotlin/io/iohk/atala/prism/apollo/derivation/EdHDKey.kt rename to apollo/src/androidMain/kotlin/io/iohk/atala/prism/apollo/derivation/EdHDKey.kt index 166c207b9..16edabf97 100644 --- a/apollo/src/allButJSMain/kotlin/io/iohk/atala/prism/apollo/derivation/EdHDKey.kt +++ b/apollo/src/androidMain/kotlin/io/iohk/atala/prism/apollo/derivation/EdHDKey.kt @@ -7,40 +7,19 @@ import io.iohk.atala.prism.apollo.utils.ECConfig /** * Represents and HDKey with its derive methods */ -class EdHDKey( - val privateKey: ByteArray, - val chainCode: ByteArray, - val publicKey: ByteArray? = null, - val depth: Int = 0, - val index: BigIntegerWrapper = BigIntegerWrapper(0) +actual class EdHDKey actual constructor( + actual val privateKey: ByteArray, + actual val chainCode: ByteArray, + actual val publicKey: ByteArray?, + actual val depth: Int, + actual val index: BigIntegerWrapper ) { - /** - * Constructs a new EdHDKey object from a seed - * - * @param seed The seed used to derive the private key and chain code. - * @throws IllegalArgumentException if the seed length is not equal to 64. - */ - fun initFromSeed(seed: ByteArray): EdHDKey { - require(seed.size == 64) { - "Seed expected byte length to be ${ECConfig.PRIVATE_KEY_BYTE_SIZE}" - } - - val key = seed.sliceArray(0 until 32) - val chainCode = seed.sliceArray(32 until seed.size) - val wrapper = XPrvWrapper.fromNonextendedNoforce(key, chainCode) - - return EdHDKey( - privateKey = wrapper.extendedSecretKey(), - chainCode = wrapper.chainCode() - ) - } - /** * Method to derive an HDKey by a path * * @param path value used to derive a key */ - fun derive(path: String): EdHDKey { + actual fun derive(path: String): EdHDKey { if (!path.matches(Regex("^[mM].*"))) { throw Error("Path must start with \"m\" or \"M\"") } @@ -70,9 +49,9 @@ class EdHDKey( /** * Method to derive an HDKey child by index * - * @param index value used to derive a key + * @param wrappedIndex value used to derive a key */ - fun deriveChild(wrappedIndex: BigIntegerWrapper): EdHDKey { + actual fun deriveChild(wrappedIndex: BigIntegerWrapper): EdHDKey { val wrapper = XPrvWrapper.fromExtendedAndChaincode(privateKey, chainCode) val derived = wrapper.derive(wrappedIndex.value.uintValue()) @@ -83,4 +62,27 @@ class EdHDKey( index = wrappedIndex ) } + + actual companion object { + /** + * Constructs a new EdHDKey object from a seed + * + * @param seed The seed used to derive the private key and chain code. + * @throws IllegalArgumentException if the seed length is not equal to 64. + */ + actual fun initFromSeed(seed: ByteArray): EdHDKey { + require(seed.size == 64) { + "Seed expected byte length to be ${ECConfig.PRIVATE_KEY_BYTE_SIZE}" + } + + val key = seed.sliceArray(0 until 32) + val chainCode = seed.sliceArray(32 until seed.size) + val wrapper = XPrvWrapper.fromNonextendedNoforce(key, chainCode) + + return EdHDKey( + privateKey = wrapper.extendedSecretKey(), + chainCode = wrapper.chainCode() + ) + } + } } diff --git a/apollo/src/androidUnitTest/kotlin/io/iohk/atala/prism/apollo/IgnoreAndroid.android.kt b/apollo/src/androidUnitTest/kotlin/io/iohk/atala/prism/apollo/IgnoreAndroid.android.kt deleted file mode 100644 index 166442dd8..000000000 --- a/apollo/src/androidUnitTest/kotlin/io/iohk/atala/prism/apollo/IgnoreAndroid.android.kt +++ /dev/null @@ -1,6 +0,0 @@ -package io.iohk.atala.prism.apollo - -/** - * Ignore unit tests in Android Target - */ -actual typealias IgnoreAndroid = org.junit.Ignore diff --git a/apollo/src/appleMain/kotlin/io/iohk/atala/prism/apollo/derivation/EdHDKey.kt b/apollo/src/appleMain/kotlin/io/iohk/atala/prism/apollo/derivation/EdHDKey.kt new file mode 100644 index 000000000..16edabf97 --- /dev/null +++ b/apollo/src/appleMain/kotlin/io/iohk/atala/prism/apollo/derivation/EdHDKey.kt @@ -0,0 +1,88 @@ +package io.iohk.atala.prism.apollo.derivation + +import com.ionspin.kotlin.bignum.integer.toBigInteger +import ed25519_bip32_wrapper.XPrvWrapper +import io.iohk.atala.prism.apollo.utils.ECConfig + +/** + * Represents and HDKey with its derive methods + */ +actual class EdHDKey actual constructor( + actual val privateKey: ByteArray, + actual val chainCode: ByteArray, + actual val publicKey: ByteArray?, + actual val depth: Int, + actual val index: BigIntegerWrapper +) { + /** + * Method to derive an HDKey by a path + * + * @param path value used to derive a key + */ + actual fun derive(path: String): EdHDKey { + if (!path.matches(Regex("^[mM].*"))) { + throw Error("Path must start with \"m\" or \"M\"") + } + if (Regex("^[mM]'?$").matches(path)) { + return this + } + val parts = path.replace(Regex("^[mM]'?/"), "").split("/") + var child = this + + for (c in parts) { + val m = Regex("^(\\d+)('?)$").find(c)?.groupValues + if (m == null || m.size != 3) { + throw Error("Invalid child index: $c") + } + val idx = m[1].toBigInteger() + if (idx >= HDKey.HARDENED_OFFSET) { + throw Error("Invalid index") + } + val finalIdx = if (m[2] == "'") idx + HDKey.HARDENED_OFFSET else idx + + child = child.deriveChild(BigIntegerWrapper(finalIdx)) + } + + return child + } + + /** + * Method to derive an HDKey child by index + * + * @param wrappedIndex value used to derive a key + */ + actual fun deriveChild(wrappedIndex: BigIntegerWrapper): EdHDKey { + val wrapper = XPrvWrapper.fromExtendedAndChaincode(privateKey, chainCode) + val derived = wrapper.derive(wrappedIndex.value.uintValue()) + + return EdHDKey( + privateKey = derived.extendedSecretKey(), + chainCode = derived.chainCode(), + depth = depth + 1, + index = wrappedIndex + ) + } + + actual companion object { + /** + * Constructs a new EdHDKey object from a seed + * + * @param seed The seed used to derive the private key and chain code. + * @throws IllegalArgumentException if the seed length is not equal to 64. + */ + actual fun initFromSeed(seed: ByteArray): EdHDKey { + require(seed.size == 64) { + "Seed expected byte length to be ${ECConfig.PRIVATE_KEY_BYTE_SIZE}" + } + + val key = seed.sliceArray(0 until 32) + val chainCode = seed.sliceArray(32 until seed.size) + val wrapper = XPrvWrapper.fromNonextendedNoforce(key, chainCode) + + return EdHDKey( + privateKey = wrapper.extendedSecretKey(), + chainCode = wrapper.chainCode() + ) + } + } +} diff --git a/apollo/src/commonMain/kotlin/io/iohk/atala/prism/apollo/derivation/EdHDKey.kt b/apollo/src/commonMain/kotlin/io/iohk/atala/prism/apollo/derivation/EdHDKey.kt new file mode 100644 index 000000000..fa291e471 --- /dev/null +++ b/apollo/src/commonMain/kotlin/io/iohk/atala/prism/apollo/derivation/EdHDKey.kt @@ -0,0 +1,42 @@ +package io.iohk.atala.prism.apollo.derivation + +/** + * Represents and HDKey with its derive methods + */ +expect class EdHDKey constructor( + privateKey: ByteArray, + chainCode: ByteArray, + publicKey: ByteArray? = null, + depth: Int = 0, + index: BigIntegerWrapper = BigIntegerWrapper(0) +) { + val privateKey: ByteArray + val chainCode: ByteArray + val publicKey: ByteArray? + val depth: Int + val index: BigIntegerWrapper + + /** + * Method to derive an HDKey by a path + * + * @param path value used to derive a key + */ + fun derive(path: String): EdHDKey + + /** + * Method to derive an HDKey child by index + * + * @param wrappedIndex value used to derive a key + */ + fun deriveChild(wrappedIndex: BigIntegerWrapper): EdHDKey + + companion object { + /** + * Constructs a new EdHDKey object from a seed + * + * @param seed The seed used to derive the private key and chain code. + * @throws IllegalArgumentException if the seed length is not equal to 64. + */ + fun initFromSeed(seed: ByteArray): EdHDKey + } +} diff --git a/apollo/src/commonTest/kotlin/io/iohk/atala/prism/apollo/IgnoreAndroid.kt b/apollo/src/commonTest/kotlin/io/iohk/atala/prism/apollo/IgnoreAndroid.kt deleted file mode 100644 index d2de0535b..000000000 --- a/apollo/src/commonTest/kotlin/io/iohk/atala/prism/apollo/IgnoreAndroid.kt +++ /dev/null @@ -1,6 +0,0 @@ -package io.iohk.atala.prism.apollo - -/** - * Ignore unit tests in Android Target - */ -expect annotation class IgnoreAndroid() diff --git a/apollo/src/commonTest/kotlin/io/iohk/atala/prism/apollo/derivation/EdHDKeyTest.kt b/apollo/src/commonTest/kotlin/io/iohk/atala/prism/apollo/derivation/EdHDKeyTest.kt new file mode 100644 index 000000000..503875e63 --- /dev/null +++ b/apollo/src/commonTest/kotlin/io/iohk/atala/prism/apollo/derivation/EdHDKeyTest.kt @@ -0,0 +1,23 @@ +package io.iohk.atala.prism.apollo.derivation + +import io.iohk.atala.prism.apollo.Platform +import io.iohk.atala.prism.apollo.utils.decodeHex +import io.iohk.atala.prism.apollo.utils.toHexString +import kotlin.test.Test +import kotlin.test.assertEquals + +class EdHDKeyTest { + @Test + fun test_derive_m1() { + if (!Platform.OS.contains("Android")) { + val privateKey = "f8a29231ee38d6c5bf715d5bac21c750577aa3798b22d79d65bf97d6fadea15adcd1ee1abdf78bd4be64731a12deb94d3671784112eb6f364b871851fd1c9a24".decodeHex() + val chainCode = "7384db9ad6003bbd08b3b1ddc0d07a597293ff85e961bf252b331262eddfad0d".decodeHex() + + val key = EdHDKey(privateKey, chainCode) + val derived = key.derive("m/1'") + + assertEquals(derived.privateKey.toHexString(), "4057eb6cab9000e3b6fe7e556341da1ca2f5dde0b689a7b58cb93f1902dfa15a5a10732ff348051c6e0865c62931d4a73fa8050b8ff543b43fc0000a7e2c5700") + assertEquals(derived.chainCode.toHexString(), "9a170f689c8b9b3502ee846f457ab3dd1b017cfb2cd68865c7f24dbabcbc2256") + } + } +} diff --git a/apollo/src/jsMain/kotlin/io/iohk/atala/prism/apollo/derivation/EdHDKey.kt b/apollo/src/jsMain/kotlin/io/iohk/atala/prism/apollo/derivation/EdHDKey.kt index 4ac9dd538..9e8849a20 100644 --- a/apollo/src/jsMain/kotlin/io/iohk/atala/prism/apollo/derivation/EdHDKey.kt +++ b/apollo/src/jsMain/kotlin/io/iohk/atala/prism/apollo/derivation/EdHDKey.kt @@ -9,42 +9,19 @@ import io.iohk.atala.prism.apollo.utils.external.ed25519_bip32 */ @OptIn(ExperimentalJsExport::class) @JsExport -class EdHDKey( - val privateKey: ByteArray, - val chainCode: ByteArray, - val publicKey: ByteArray? = null, - val depth: Int = 0, - val index: BigIntegerWrapper = BigIntegerWrapper(0) +actual class EdHDKey actual constructor( + actual val privateKey: ByteArray, + actual val chainCode: ByteArray, + actual val publicKey: ByteArray?, + actual val depth: Int, + actual val index: BigIntegerWrapper ) { - companion object { - /** - * Constructs a new EdHDKey object from a seed - * - * @param seed The seed used to derive the private key and chain code. - * @throws IllegalArgumentException if the seed length is not equal to 64. - */ - fun initFromSeed(seed: ByteArray): EdHDKey { - require(seed.size == 64) { - "Seed expected byte length to be ${ECConfig.PRIVATE_KEY_BYTE_SIZE}" - } - - val key = seed.sliceArray(0 until 32) - val chainCode = seed.sliceArray(32 until seed.size) - val wrapper = ed25519_bip32.XPrvWrapper.from_nonextended_noforce(key, chainCode) - - return EdHDKey( - privateKey = wrapper.extended_secret_key(), - chainCode = wrapper.chain_code() - ) - } - } - /** * Method to derive an HDKey by a path * * @param path value used to derive a key */ - fun derive(path: String): EdHDKey { + actual fun derive(path: String): EdHDKey { if (!path.matches(Regex("^[mM].*"))) { throw Error("Path must start with \"m\" or \"M\"") } @@ -74,9 +51,9 @@ class EdHDKey( /** * Method to derive an HDKey child by index * - * @param index value used to derive a key + * @param wrappedIndex value used to derive a key */ - fun deriveChild(wrappedIndex: BigIntegerWrapper): EdHDKey { + actual fun deriveChild(wrappedIndex: BigIntegerWrapper): EdHDKey { val wrapper = ed25519_bip32.XPrvWrapper.from_extended_and_chaincode(privateKey, chainCode) val derived = wrapper.derive(wrappedIndex.value.uintValue()) @@ -87,4 +64,27 @@ class EdHDKey( index = wrappedIndex ) } + + actual companion object { + /** + * Constructs a new EdHDKey object from a seed + * + * @param seed The seed used to derive the private key and chain code. + * @throws IllegalArgumentException if the seed length is not equal to 64. + */ + actual fun initFromSeed(seed: ByteArray): EdHDKey { + require(seed.size == 64) { + "Seed expected byte length to be ${ECConfig.PRIVATE_KEY_BYTE_SIZE}" + } + + val key = seed.sliceArray(0 until 32) + val chainCode = seed.sliceArray(32 until seed.size) + val wrapper = ed25519_bip32.XPrvWrapper.from_nonextended_noforce(key, chainCode) + + return EdHDKey( + privateKey = wrapper.extended_secret_key(), + chainCode = wrapper.chain_code() + ) + } + } } diff --git a/apollo/src/jsTest/kotlin/io/iohk/atala/prism/apollo/IgnoreAndroid.js.kt b/apollo/src/jsTest/kotlin/io/iohk/atala/prism/apollo/IgnoreAndroid.js.kt deleted file mode 100644 index 3317eb5d4..000000000 --- a/apollo/src/jsTest/kotlin/io/iohk/atala/prism/apollo/IgnoreAndroid.js.kt +++ /dev/null @@ -1,6 +0,0 @@ -package io.iohk.atala.prism.apollo - -/** - * Ignore unit tests in Android Target - */ -actual annotation class IgnoreAndroid diff --git a/apollo/src/jvmMain/kotlin/io/iohk/atala/prism/apollo/derivation/EdHDKey.kt b/apollo/src/jvmMain/kotlin/io/iohk/atala/prism/apollo/derivation/EdHDKey.kt new file mode 100644 index 000000000..16edabf97 --- /dev/null +++ b/apollo/src/jvmMain/kotlin/io/iohk/atala/prism/apollo/derivation/EdHDKey.kt @@ -0,0 +1,88 @@ +package io.iohk.atala.prism.apollo.derivation + +import com.ionspin.kotlin.bignum.integer.toBigInteger +import ed25519_bip32_wrapper.XPrvWrapper +import io.iohk.atala.prism.apollo.utils.ECConfig + +/** + * Represents and HDKey with its derive methods + */ +actual class EdHDKey actual constructor( + actual val privateKey: ByteArray, + actual val chainCode: ByteArray, + actual val publicKey: ByteArray?, + actual val depth: Int, + actual val index: BigIntegerWrapper +) { + /** + * Method to derive an HDKey by a path + * + * @param path value used to derive a key + */ + actual fun derive(path: String): EdHDKey { + if (!path.matches(Regex("^[mM].*"))) { + throw Error("Path must start with \"m\" or \"M\"") + } + if (Regex("^[mM]'?$").matches(path)) { + return this + } + val parts = path.replace(Regex("^[mM]'?/"), "").split("/") + var child = this + + for (c in parts) { + val m = Regex("^(\\d+)('?)$").find(c)?.groupValues + if (m == null || m.size != 3) { + throw Error("Invalid child index: $c") + } + val idx = m[1].toBigInteger() + if (idx >= HDKey.HARDENED_OFFSET) { + throw Error("Invalid index") + } + val finalIdx = if (m[2] == "'") idx + HDKey.HARDENED_OFFSET else idx + + child = child.deriveChild(BigIntegerWrapper(finalIdx)) + } + + return child + } + + /** + * Method to derive an HDKey child by index + * + * @param wrappedIndex value used to derive a key + */ + actual fun deriveChild(wrappedIndex: BigIntegerWrapper): EdHDKey { + val wrapper = XPrvWrapper.fromExtendedAndChaincode(privateKey, chainCode) + val derived = wrapper.derive(wrappedIndex.value.uintValue()) + + return EdHDKey( + privateKey = derived.extendedSecretKey(), + chainCode = derived.chainCode(), + depth = depth + 1, + index = wrappedIndex + ) + } + + actual companion object { + /** + * Constructs a new EdHDKey object from a seed + * + * @param seed The seed used to derive the private key and chain code. + * @throws IllegalArgumentException if the seed length is not equal to 64. + */ + actual fun initFromSeed(seed: ByteArray): EdHDKey { + require(seed.size == 64) { + "Seed expected byte length to be ${ECConfig.PRIVATE_KEY_BYTE_SIZE}" + } + + val key = seed.sliceArray(0 until 32) + val chainCode = seed.sliceArray(32 until seed.size) + val wrapper = XPrvWrapper.fromNonextendedNoforce(key, chainCode) + + return EdHDKey( + privateKey = wrapper.extendedSecretKey(), + chainCode = wrapper.chainCode() + ) + } + } +} diff --git a/apollo/src/jvmTest/kotlin/io/iohk/atala/prism/apollo/IgnoreAndroid.jvm.kt b/apollo/src/jvmTest/kotlin/io/iohk/atala/prism/apollo/IgnoreAndroid.jvm.kt deleted file mode 100644 index 3317eb5d4..000000000 --- a/apollo/src/jvmTest/kotlin/io/iohk/atala/prism/apollo/IgnoreAndroid.jvm.kt +++ /dev/null @@ -1,6 +0,0 @@ -package io.iohk.atala.prism.apollo - -/** - * Ignore unit tests in Android Target - */ -actual annotation class IgnoreAndroid diff --git a/apollo/src/nativeTest/kotlin/io/iohk/atala/prism/apollo/IgnoreAndroid.native.kt b/apollo/src/nativeTest/kotlin/io/iohk/atala/prism/apollo/IgnoreAndroid.native.kt deleted file mode 100644 index 3317eb5d4..000000000 --- a/apollo/src/nativeTest/kotlin/io/iohk/atala/prism/apollo/IgnoreAndroid.native.kt +++ /dev/null @@ -1,6 +0,0 @@ -package io.iohk.atala.prism.apollo - -/** - * Ignore unit tests in Android Target - */ -actual annotation class IgnoreAndroid diff --git a/build.gradle.kts b/build.gradle.kts index 2880cd19c..cc769f2c5 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -19,7 +19,7 @@ buildscript { mavenCentral() } dependencies { - classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.22") + classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.23") classpath("org.jetbrains.dokka:dokka-base:1.9.20") } } From 9f51874490381505b4a441714eb817ad5ac0c0ad Mon Sep 17 00:00:00 2001 From: Curtish Date: Tue, 7 May 2024 09:05:16 +0100 Subject: [PATCH 22/39] lint fix Signed-off-by: Curtish --- .../kotlin/io/iohk/atala/prism/apollo/derivation/EdHDKey.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apollo/src/commonMain/kotlin/io/iohk/atala/prism/apollo/derivation/EdHDKey.kt b/apollo/src/commonMain/kotlin/io/iohk/atala/prism/apollo/derivation/EdHDKey.kt index fa291e471..fb32a38b3 100644 --- a/apollo/src/commonMain/kotlin/io/iohk/atala/prism/apollo/derivation/EdHDKey.kt +++ b/apollo/src/commonMain/kotlin/io/iohk/atala/prism/apollo/derivation/EdHDKey.kt @@ -9,7 +9,7 @@ expect class EdHDKey constructor( publicKey: ByteArray? = null, depth: Int = 0, index: BigIntegerWrapper = BigIntegerWrapper(0) -) { +) { val privateKey: ByteArray val chainCode: ByteArray val publicKey: ByteArray? From 8d2210c7c2b776ed5de2b03a04e402823e2b95dd Mon Sep 17 00:00:00 2001 From: Curtish Date: Tue, 7 May 2024 13:35:00 +0100 Subject: [PATCH 23/39] ci fix - install build-essentials Signed-off-by: Curtis Harding --- .github/workflows/pull-request.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml index 0a3118765..496170a69 100644 --- a/.github/workflows/pull-request.yml +++ b/.github/workflows/pull-request.yml @@ -65,7 +65,7 @@ jobs: - name: "Install rust toolchain (Linux)" if: matrix.os-type == 'linux' - run: sudo apt install rustc -y + run: sudo apt install rustc build-essential -y - name: "Install rust toolchain (Macos)" if: matrix.os-type == 'macos' From 252502dba37d31afc08029e65e165b56ee9c7cef Mon Sep 17 00:00:00 2001 From: Curtish Date: Tue, 7 May 2024 14:56:39 +0100 Subject: [PATCH 24/39] rust-ed25519-bip32 submodule update Signed-off-by: Curtis Harding --- rust-ed25519-bip32 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-ed25519-bip32 b/rust-ed25519-bip32 index f8d97b2bf..3ae00c0fb 160000 --- a/rust-ed25519-bip32 +++ b/rust-ed25519-bip32 @@ -1 +1 @@ -Subproject commit f8d97b2bf4e77fcc07fe49843f0597c6a83be06b +Subproject commit 3ae00c0fbf17999e6e95debe732c1ff4c1c7a689 From abc5f2afd8370f428a5ad61bd3915a3eb7200573 Mon Sep 17 00:00:00 2001 From: Curtish Date: Tue, 7 May 2024 15:21:51 +0100 Subject: [PATCH 25/39] rust-ed25519-bip32 submodule update Signed-off-by: Curtis Harding --- rust-ed25519-bip32 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-ed25519-bip32 b/rust-ed25519-bip32 index 3ae00c0fb..f89c115f0 160000 --- a/rust-ed25519-bip32 +++ b/rust-ed25519-bip32 @@ -1 +1 @@ -Subproject commit 3ae00c0fbf17999e6e95debe732c1ff4c1c7a689 +Subproject commit f89c115f0537e399a83380c3236ae4fb3209f325 From baf81f92876ad744762156934c55431db2517119 Mon Sep 17 00:00:00 2001 From: Curtish Date: Tue, 7 May 2024 18:08:31 +0100 Subject: [PATCH 26/39] rust-ed25519-bip32 submodule update Signed-off-by: Curtis Harding --- rust-ed25519-bip32 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-ed25519-bip32 b/rust-ed25519-bip32 index f89c115f0..5ff45aab7 160000 --- a/rust-ed25519-bip32 +++ b/rust-ed25519-bip32 @@ -1 +1 @@ -Subproject commit f89c115f0537e399a83380c3236ae4fb3209f325 +Subproject commit 5ff45aab71841941e06fd482691217e9ea80dc05 From 3ca4e01658ec7e0c77cab24cd3f67065f2b5da61 Mon Sep 17 00:00:00 2001 From: Curtish Date: Wed, 8 May 2024 11:16:31 +0100 Subject: [PATCH 27/39] rust-ed25519-bip32 submodule update Signed-off-by: Curtis Harding --- apollo/build.gradle.kts | 8 ++++++++ rust-ed25519-bip32 | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/apollo/build.gradle.kts b/apollo/build.gradle.kts index d563be138..e59d4e496 100644 --- a/apollo/build.gradle.kts +++ b/apollo/build.gradle.kts @@ -20,6 +20,8 @@ val ed25519bip32Dir = rootDir.resolve("rust-ed25519-bip32") val generatedDir = project.layout.buildDirectory.asFile.get().resolve("generated") val generatedResourcesDir = project.layout.buildDirectory.asFile.get().resolve("generatedResources") val ed25519bip32BinariesDir = ed25519bip32Dir.resolve("wrapper").resolve("target") +val ANDROID_SDK = System.getenv("ANDROID_HOME") +val NDK = System.getenv("ANDROID_NDK_HOME") plugins { kotlin("multiplatform") @@ -307,6 +309,12 @@ val copyEd25519Bip32Wrapper by tasks.register("copyEd25519Bip32") { val buildEd25519Bip32Wrapper by tasks.register("buildEd25519Bip32Wrapper") { group = taskGroup workingDir = ed25519bip32Dir.resolve("wrapper") + val localEnv = this.environment + localEnv += mapOf( + "ANDROID_HOME" to ANDROID_SDK, + "ANDROID_NDK_HOME" to NDK + ) + this.environment = localEnv commandLine("./build-kotlin-library.sh") } diff --git a/rust-ed25519-bip32 b/rust-ed25519-bip32 index 5ff45aab7..ca06809ca 160000 --- a/rust-ed25519-bip32 +++ b/rust-ed25519-bip32 @@ -1 +1 @@ -Subproject commit 5ff45aab71841941e06fd482691217e9ea80dc05 +Subproject commit ca06809caeac0591538eadb6bbb3b110fefc993b From 7d0ea3d0bdde0a4411471e4b681d369cb0432196 Mon Sep 17 00:00:00 2001 From: Curtish Date: Wed, 8 May 2024 15:35:11 +0100 Subject: [PATCH 28/39] rust-ed25519-bip32 submodule update Signed-off-by: Curtis Harding --- rust-ed25519-bip32 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-ed25519-bip32 b/rust-ed25519-bip32 index ca06809ca..f6b4cce83 160000 --- a/rust-ed25519-bip32 +++ b/rust-ed25519-bip32 @@ -1 +1 @@ -Subproject commit ca06809caeac0591538eadb6bbb3b110fefc993b +Subproject commit f6b4cce83b503b2b6b4293dc3e479f521d57d3d4 From 50cd101b9d31fdb169b78896ede1f5a9d40260ce Mon Sep 17 00:00:00 2001 From: Curtish Date: Mon, 13 May 2024 11:37:27 +0100 Subject: [PATCH 29/39] rust-ed25519-bip32 submodule pivot to functions Signed-off-by: Curtis Harding --- .../atala/prism/apollo/derivation/EdHDKey.kt | 33 +++++++++++++------ .../atala/prism/apollo/derivation/EdHDKey.kt | 33 +++++++++++++------ .../atala/prism/apollo/derivation/EdHDKey.kt | 33 +++++++++++++------ rust-ed25519-bip32 | 2 +- 4 files changed, 70 insertions(+), 31 deletions(-) diff --git a/apollo/src/androidMain/kotlin/io/iohk/atala/prism/apollo/derivation/EdHDKey.kt b/apollo/src/androidMain/kotlin/io/iohk/atala/prism/apollo/derivation/EdHDKey.kt index 16edabf97..aa0231424 100644 --- a/apollo/src/androidMain/kotlin/io/iohk/atala/prism/apollo/derivation/EdHDKey.kt +++ b/apollo/src/androidMain/kotlin/io/iohk/atala/prism/apollo/derivation/EdHDKey.kt @@ -1,7 +1,8 @@ package io.iohk.atala.prism.apollo.derivation import com.ionspin.kotlin.bignum.integer.toBigInteger -import ed25519_bip32_wrapper.XPrvWrapper +import ed25519_bip32_wrapper.deriveBytes +import ed25519_bip32_wrapper.fromNonextendedNoforce import io.iohk.atala.prism.apollo.utils.ECConfig /** @@ -52,12 +53,18 @@ actual class EdHDKey actual constructor( * @param wrappedIndex value used to derive a key */ actual fun deriveChild(wrappedIndex: BigIntegerWrapper): EdHDKey { - val wrapper = XPrvWrapper.fromExtendedAndChaincode(privateKey, chainCode) - val derived = wrapper.derive(wrappedIndex.value.uintValue()) + val index = wrappedIndex.value.uintValue() + val derived = deriveBytes(privateKey, chainCode, index) + val secretKey = derived["secret_key"] + val chainCode = derived["chain_code"] + + if(secretKey == null || chainCode == null) { + throw Error("Unable to derive key") + } return EdHDKey( - privateKey = derived.extendedSecretKey(), - chainCode = derived.chainCode(), + privateKey = secretKey, + chainCode = chainCode, depth = depth + 1, index = wrappedIndex ) @@ -75,13 +82,19 @@ actual class EdHDKey actual constructor( "Seed expected byte length to be ${ECConfig.PRIVATE_KEY_BYTE_SIZE}" } - val key = seed.sliceArray(0 until 32) - val chainCode = seed.sliceArray(32 until seed.size) - val wrapper = XPrvWrapper.fromNonextendedNoforce(key, chainCode) + val keySlice = seed.sliceArray(0 until 32) + val chainCodeSlice = seed.sliceArray(32 until seed.size) + val result = fromNonextendedNoforce(keySlice, chainCodeSlice) + val secretKey = result["secret_key"] + val chainCode = result["chain_code"] + + if(secretKey == null || chainCode == null) { + throw Error("Unable to derive key") + } return EdHDKey( - privateKey = wrapper.extendedSecretKey(), - chainCode = wrapper.chainCode() + privateKey = secretKey, + chainCode = chainCode ) } } diff --git a/apollo/src/appleMain/kotlin/io/iohk/atala/prism/apollo/derivation/EdHDKey.kt b/apollo/src/appleMain/kotlin/io/iohk/atala/prism/apollo/derivation/EdHDKey.kt index 16edabf97..aa0231424 100644 --- a/apollo/src/appleMain/kotlin/io/iohk/atala/prism/apollo/derivation/EdHDKey.kt +++ b/apollo/src/appleMain/kotlin/io/iohk/atala/prism/apollo/derivation/EdHDKey.kt @@ -1,7 +1,8 @@ package io.iohk.atala.prism.apollo.derivation import com.ionspin.kotlin.bignum.integer.toBigInteger -import ed25519_bip32_wrapper.XPrvWrapper +import ed25519_bip32_wrapper.deriveBytes +import ed25519_bip32_wrapper.fromNonextendedNoforce import io.iohk.atala.prism.apollo.utils.ECConfig /** @@ -52,12 +53,18 @@ actual class EdHDKey actual constructor( * @param wrappedIndex value used to derive a key */ actual fun deriveChild(wrappedIndex: BigIntegerWrapper): EdHDKey { - val wrapper = XPrvWrapper.fromExtendedAndChaincode(privateKey, chainCode) - val derived = wrapper.derive(wrappedIndex.value.uintValue()) + val index = wrappedIndex.value.uintValue() + val derived = deriveBytes(privateKey, chainCode, index) + val secretKey = derived["secret_key"] + val chainCode = derived["chain_code"] + + if(secretKey == null || chainCode == null) { + throw Error("Unable to derive key") + } return EdHDKey( - privateKey = derived.extendedSecretKey(), - chainCode = derived.chainCode(), + privateKey = secretKey, + chainCode = chainCode, depth = depth + 1, index = wrappedIndex ) @@ -75,13 +82,19 @@ actual class EdHDKey actual constructor( "Seed expected byte length to be ${ECConfig.PRIVATE_KEY_BYTE_SIZE}" } - val key = seed.sliceArray(0 until 32) - val chainCode = seed.sliceArray(32 until seed.size) - val wrapper = XPrvWrapper.fromNonextendedNoforce(key, chainCode) + val keySlice = seed.sliceArray(0 until 32) + val chainCodeSlice = seed.sliceArray(32 until seed.size) + val result = fromNonextendedNoforce(keySlice, chainCodeSlice) + val secretKey = result["secret_key"] + val chainCode = result["chain_code"] + + if(secretKey == null || chainCode == null) { + throw Error("Unable to derive key") + } return EdHDKey( - privateKey = wrapper.extendedSecretKey(), - chainCode = wrapper.chainCode() + privateKey = secretKey, + chainCode = chainCode ) } } diff --git a/apollo/src/jvmMain/kotlin/io/iohk/atala/prism/apollo/derivation/EdHDKey.kt b/apollo/src/jvmMain/kotlin/io/iohk/atala/prism/apollo/derivation/EdHDKey.kt index 16edabf97..aa0231424 100644 --- a/apollo/src/jvmMain/kotlin/io/iohk/atala/prism/apollo/derivation/EdHDKey.kt +++ b/apollo/src/jvmMain/kotlin/io/iohk/atala/prism/apollo/derivation/EdHDKey.kt @@ -1,7 +1,8 @@ package io.iohk.atala.prism.apollo.derivation import com.ionspin.kotlin.bignum.integer.toBigInteger -import ed25519_bip32_wrapper.XPrvWrapper +import ed25519_bip32_wrapper.deriveBytes +import ed25519_bip32_wrapper.fromNonextendedNoforce import io.iohk.atala.prism.apollo.utils.ECConfig /** @@ -52,12 +53,18 @@ actual class EdHDKey actual constructor( * @param wrappedIndex value used to derive a key */ actual fun deriveChild(wrappedIndex: BigIntegerWrapper): EdHDKey { - val wrapper = XPrvWrapper.fromExtendedAndChaincode(privateKey, chainCode) - val derived = wrapper.derive(wrappedIndex.value.uintValue()) + val index = wrappedIndex.value.uintValue() + val derived = deriveBytes(privateKey, chainCode, index) + val secretKey = derived["secret_key"] + val chainCode = derived["chain_code"] + + if(secretKey == null || chainCode == null) { + throw Error("Unable to derive key") + } return EdHDKey( - privateKey = derived.extendedSecretKey(), - chainCode = derived.chainCode(), + privateKey = secretKey, + chainCode = chainCode, depth = depth + 1, index = wrappedIndex ) @@ -75,13 +82,19 @@ actual class EdHDKey actual constructor( "Seed expected byte length to be ${ECConfig.PRIVATE_KEY_BYTE_SIZE}" } - val key = seed.sliceArray(0 until 32) - val chainCode = seed.sliceArray(32 until seed.size) - val wrapper = XPrvWrapper.fromNonextendedNoforce(key, chainCode) + val keySlice = seed.sliceArray(0 until 32) + val chainCodeSlice = seed.sliceArray(32 until seed.size) + val result = fromNonextendedNoforce(keySlice, chainCodeSlice) + val secretKey = result["secret_key"] + val chainCode = result["chain_code"] + + if(secretKey == null || chainCode == null) { + throw Error("Unable to derive key") + } return EdHDKey( - privateKey = wrapper.extendedSecretKey(), - chainCode = wrapper.chainCode() + privateKey = secretKey, + chainCode = chainCode ) } } diff --git a/rust-ed25519-bip32 b/rust-ed25519-bip32 index f6b4cce83..91354a1e7 160000 --- a/rust-ed25519-bip32 +++ b/rust-ed25519-bip32 @@ -1 +1 @@ -Subproject commit f6b4cce83b503b2b6b4293dc3e479f521d57d3d4 +Subproject commit 91354a1e777c3e2f4bd0859734977b86217e8fbe From 484dbcde4732f8a613a3e85b168890301e126717 Mon Sep 17 00:00:00 2001 From: Curtish Date: Mon, 13 May 2024 11:43:07 +0100 Subject: [PATCH 30/39] lint Signed-off-by: Curtis Harding --- .../kotlin/io/iohk/atala/prism/apollo/derivation/EdHDKey.kt | 4 ++-- .../kotlin/io/iohk/atala/prism/apollo/derivation/EdHDKey.kt | 4 ++-- .../kotlin/io/iohk/atala/prism/apollo/derivation/EdHDKey.kt | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/apollo/src/androidMain/kotlin/io/iohk/atala/prism/apollo/derivation/EdHDKey.kt b/apollo/src/androidMain/kotlin/io/iohk/atala/prism/apollo/derivation/EdHDKey.kt index aa0231424..052865dc2 100644 --- a/apollo/src/androidMain/kotlin/io/iohk/atala/prism/apollo/derivation/EdHDKey.kt +++ b/apollo/src/androidMain/kotlin/io/iohk/atala/prism/apollo/derivation/EdHDKey.kt @@ -58,7 +58,7 @@ actual class EdHDKey actual constructor( val secretKey = derived["secret_key"] val chainCode = derived["chain_code"] - if(secretKey == null || chainCode == null) { + if (secretKey == null || chainCode == null) { throw Error("Unable to derive key") } @@ -88,7 +88,7 @@ actual class EdHDKey actual constructor( val secretKey = result["secret_key"] val chainCode = result["chain_code"] - if(secretKey == null || chainCode == null) { + if (secretKey == null || chainCode == null) { throw Error("Unable to derive key") } diff --git a/apollo/src/appleMain/kotlin/io/iohk/atala/prism/apollo/derivation/EdHDKey.kt b/apollo/src/appleMain/kotlin/io/iohk/atala/prism/apollo/derivation/EdHDKey.kt index aa0231424..052865dc2 100644 --- a/apollo/src/appleMain/kotlin/io/iohk/atala/prism/apollo/derivation/EdHDKey.kt +++ b/apollo/src/appleMain/kotlin/io/iohk/atala/prism/apollo/derivation/EdHDKey.kt @@ -58,7 +58,7 @@ actual class EdHDKey actual constructor( val secretKey = derived["secret_key"] val chainCode = derived["chain_code"] - if(secretKey == null || chainCode == null) { + if (secretKey == null || chainCode == null) { throw Error("Unable to derive key") } @@ -88,7 +88,7 @@ actual class EdHDKey actual constructor( val secretKey = result["secret_key"] val chainCode = result["chain_code"] - if(secretKey == null || chainCode == null) { + if (secretKey == null || chainCode == null) { throw Error("Unable to derive key") } diff --git a/apollo/src/jvmMain/kotlin/io/iohk/atala/prism/apollo/derivation/EdHDKey.kt b/apollo/src/jvmMain/kotlin/io/iohk/atala/prism/apollo/derivation/EdHDKey.kt index aa0231424..052865dc2 100644 --- a/apollo/src/jvmMain/kotlin/io/iohk/atala/prism/apollo/derivation/EdHDKey.kt +++ b/apollo/src/jvmMain/kotlin/io/iohk/atala/prism/apollo/derivation/EdHDKey.kt @@ -58,7 +58,7 @@ actual class EdHDKey actual constructor( val secretKey = derived["secret_key"] val chainCode = derived["chain_code"] - if(secretKey == null || chainCode == null) { + if (secretKey == null || chainCode == null) { throw Error("Unable to derive key") } @@ -88,7 +88,7 @@ actual class EdHDKey actual constructor( val secretKey = result["secret_key"] val chainCode = result["chain_code"] - if(secretKey == null || chainCode == null) { + if (secretKey == null || chainCode == null) { throw Error("Unable to derive key") } From 5d30c5dcf2a8403cbdac2cda80e88ada2db9be23 Mon Sep 17 00:00:00 2001 From: Curtish Date: Mon, 13 May 2024 11:59:22 +0100 Subject: [PATCH 31/39] jsTest fix attempt Signed-off-by: Curtis Harding --- apollo/webpack.config.d/polyfill.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apollo/webpack.config.d/polyfill.js b/apollo/webpack.config.d/polyfill.js index 1c40c5b92..7ee4c26bc 100644 --- a/apollo/webpack.config.d/polyfill.js +++ b/apollo/webpack.config.d/polyfill.js @@ -1,7 +1,7 @@ config.resolve = { fallback: { stream: require.resolve("stream-browserify"), - "url": require.resolve("url/") + url: require.resolve("url") } }; var webpack = require('webpack'); From c72b95bcda6768a01d715038553b4e434702fb64 Mon Sep 17 00:00:00 2001 From: Curtish Date: Mon, 13 May 2024 12:42:29 +0100 Subject: [PATCH 32/39] rust-ed25519-bip32 submodule update Signed-off-by: Curtis Harding --- rust-ed25519-bip32 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-ed25519-bip32 b/rust-ed25519-bip32 index 91354a1e7..944c30b45 160000 --- a/rust-ed25519-bip32 +++ b/rust-ed25519-bip32 @@ -1 +1 @@ -Subproject commit 91354a1e777c3e2f4bd0859734977b86217e8fbe +Subproject commit 944c30b450825b3d7bcb4479285289aa0c6b63c4 From 6da3614500c2cee5b075dfda238b44b054602a10 Mon Sep 17 00:00:00 2001 From: Curtish Date: Mon, 13 May 2024 15:13:33 +0100 Subject: [PATCH 33/39] rust-ed25519-bip32 submodule update Signed-off-by: Curtis Harding --- rust-ed25519-bip32 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-ed25519-bip32 b/rust-ed25519-bip32 index 944c30b45..c694d831b 160000 --- a/rust-ed25519-bip32 +++ b/rust-ed25519-bip32 @@ -1 +1 @@ -Subproject commit 944c30b450825b3d7bcb4479285289aa0c6b63c4 +Subproject commit c694d831bf7908a807bc6c85dadf30bb71a60b6a From cbbe5f8f030fdb890396674b8b6b1f864752933b Mon Sep 17 00:00:00 2001 From: Curtish Date: Tue, 14 May 2024 11:22:15 +0100 Subject: [PATCH 34/39] rust-ed25519-bip32 submodule update Signed-off-by: Curtis Harding --- .../atala/prism/apollo/derivation/EdHDKey.kt | 13 ++++++------- .../apollo/utils/external/Ed25519_Bip32.kt | 18 +++--------------- rust-ed25519-bip32 | 2 +- 3 files changed, 10 insertions(+), 23 deletions(-) diff --git a/apollo/src/jsMain/kotlin/io/iohk/atala/prism/apollo/derivation/EdHDKey.kt b/apollo/src/jsMain/kotlin/io/iohk/atala/prism/apollo/derivation/EdHDKey.kt index 9e8849a20..0e8cbf188 100644 --- a/apollo/src/jsMain/kotlin/io/iohk/atala/prism/apollo/derivation/EdHDKey.kt +++ b/apollo/src/jsMain/kotlin/io/iohk/atala/prism/apollo/derivation/EdHDKey.kt @@ -54,12 +54,11 @@ actual class EdHDKey actual constructor( * @param wrappedIndex value used to derive a key */ actual fun deriveChild(wrappedIndex: BigIntegerWrapper): EdHDKey { - val wrapper = ed25519_bip32.XPrvWrapper.from_extended_and_chaincode(privateKey, chainCode) - val derived = wrapper.derive(wrappedIndex.value.uintValue()) + val derived = ed25519_bip32.derive_bytes(privateKey, chainCode, wrappedIndex.value.uintValue()); return EdHDKey( - privateKey = derived.extended_secret_key(), - chainCode = derived.chain_code(), + privateKey = derived[0], + chainCode = derived[1], depth = depth + 1, index = wrappedIndex ) @@ -79,11 +78,11 @@ actual class EdHDKey actual constructor( val key = seed.sliceArray(0 until 32) val chainCode = seed.sliceArray(32 until seed.size) - val wrapper = ed25519_bip32.XPrvWrapper.from_nonextended_noforce(key, chainCode) + val result = ed25519_bip32.from_nonextended_noforce(key, chainCode) return EdHDKey( - privateKey = wrapper.extended_secret_key(), - chainCode = wrapper.chain_code() + privateKey = result[0], + chainCode = result[1] ) } } diff --git a/apollo/src/jsMain/kotlin/io/iohk/atala/prism/apollo/utils/external/Ed25519_Bip32.kt b/apollo/src/jsMain/kotlin/io/iohk/atala/prism/apollo/utils/external/Ed25519_Bip32.kt index ee3b4cf3f..bda38b718 100644 --- a/apollo/src/jsMain/kotlin/io/iohk/atala/prism/apollo/utils/external/Ed25519_Bip32.kt +++ b/apollo/src/jsMain/kotlin/io/iohk/atala/prism/apollo/utils/external/Ed25519_Bip32.kt @@ -1,21 +1,9 @@ package io.iohk.atala.prism.apollo.utils.external -external interface XPrvWrapper { - fun public(): ByteArray - - fun derive(index: Any): XPrvWrapper - - fun extended_secret_key(): ByteArray - - fun chain_code(): ByteArray - - var from_nonextended_noforce: (js_bytes: ByteArray, js_chain_code: ByteArray) -> XPrvWrapper - - var from_extended_and_chaincode: (js_bytes: ByteArray, js_chain_code: ByteArray) -> XPrvWrapper -} - external interface ed25519_bip32_export { - var XPrvWrapper: XPrvWrapper + fun from_nonextended_noforce(key: ByteArray, chain_code: ByteArray): Array + + fun derive_bytes(key: ByteArray, chain_code: ByteArray, index: Any): Array } @JsModule("./ed25519_bip32_wasm.js") diff --git a/rust-ed25519-bip32 b/rust-ed25519-bip32 index c694d831b..975e9e608 160000 --- a/rust-ed25519-bip32 +++ b/rust-ed25519-bip32 @@ -1 +1 @@ -Subproject commit c694d831bf7908a807bc6c85dadf30bb71a60b6a +Subproject commit 975e9e608ffe3d3e5095e32357056ed4bdfb9f54 From b3e68f62f294d08937605075883245cea02e7af7 Mon Sep 17 00:00:00 2001 From: Curtish Date: Wed, 15 May 2024 09:15:51 +0100 Subject: [PATCH 35/39] removing EdHDKey public key property Signed-off-by: Curtis Harding --- .../kotlin/io/iohk/atala/prism/apollo/derivation/EdHDKey.kt | 1 - .../kotlin/io/iohk/atala/prism/apollo/derivation/EdHDKey.kt | 1 - .../kotlin/io/iohk/atala/prism/apollo/derivation/EdHDKey.kt | 2 -- .../kotlin/io/iohk/atala/prism/apollo/derivation/EdHDKey.kt | 3 +-- .../kotlin/io/iohk/atala/prism/apollo/derivation/EdHDKey.kt | 1 - 5 files changed, 1 insertion(+), 7 deletions(-) diff --git a/apollo/src/androidMain/kotlin/io/iohk/atala/prism/apollo/derivation/EdHDKey.kt b/apollo/src/androidMain/kotlin/io/iohk/atala/prism/apollo/derivation/EdHDKey.kt index 052865dc2..68d68624d 100644 --- a/apollo/src/androidMain/kotlin/io/iohk/atala/prism/apollo/derivation/EdHDKey.kt +++ b/apollo/src/androidMain/kotlin/io/iohk/atala/prism/apollo/derivation/EdHDKey.kt @@ -11,7 +11,6 @@ import io.iohk.atala.prism.apollo.utils.ECConfig actual class EdHDKey actual constructor( actual val privateKey: ByteArray, actual val chainCode: ByteArray, - actual val publicKey: ByteArray?, actual val depth: Int, actual val index: BigIntegerWrapper ) { diff --git a/apollo/src/appleMain/kotlin/io/iohk/atala/prism/apollo/derivation/EdHDKey.kt b/apollo/src/appleMain/kotlin/io/iohk/atala/prism/apollo/derivation/EdHDKey.kt index 052865dc2..68d68624d 100644 --- a/apollo/src/appleMain/kotlin/io/iohk/atala/prism/apollo/derivation/EdHDKey.kt +++ b/apollo/src/appleMain/kotlin/io/iohk/atala/prism/apollo/derivation/EdHDKey.kt @@ -11,7 +11,6 @@ import io.iohk.atala.prism.apollo.utils.ECConfig actual class EdHDKey actual constructor( actual val privateKey: ByteArray, actual val chainCode: ByteArray, - actual val publicKey: ByteArray?, actual val depth: Int, actual val index: BigIntegerWrapper ) { diff --git a/apollo/src/commonMain/kotlin/io/iohk/atala/prism/apollo/derivation/EdHDKey.kt b/apollo/src/commonMain/kotlin/io/iohk/atala/prism/apollo/derivation/EdHDKey.kt index fb32a38b3..dbbc87344 100644 --- a/apollo/src/commonMain/kotlin/io/iohk/atala/prism/apollo/derivation/EdHDKey.kt +++ b/apollo/src/commonMain/kotlin/io/iohk/atala/prism/apollo/derivation/EdHDKey.kt @@ -6,13 +6,11 @@ package io.iohk.atala.prism.apollo.derivation expect class EdHDKey constructor( privateKey: ByteArray, chainCode: ByteArray, - publicKey: ByteArray? = null, depth: Int = 0, index: BigIntegerWrapper = BigIntegerWrapper(0) ) { val privateKey: ByteArray val chainCode: ByteArray - val publicKey: ByteArray? val depth: Int val index: BigIntegerWrapper diff --git a/apollo/src/jsMain/kotlin/io/iohk/atala/prism/apollo/derivation/EdHDKey.kt b/apollo/src/jsMain/kotlin/io/iohk/atala/prism/apollo/derivation/EdHDKey.kt index 0e8cbf188..022463536 100644 --- a/apollo/src/jsMain/kotlin/io/iohk/atala/prism/apollo/derivation/EdHDKey.kt +++ b/apollo/src/jsMain/kotlin/io/iohk/atala/prism/apollo/derivation/EdHDKey.kt @@ -12,7 +12,6 @@ import io.iohk.atala.prism.apollo.utils.external.ed25519_bip32 actual class EdHDKey actual constructor( actual val privateKey: ByteArray, actual val chainCode: ByteArray, - actual val publicKey: ByteArray?, actual val depth: Int, actual val index: BigIntegerWrapper ) { @@ -54,7 +53,7 @@ actual class EdHDKey actual constructor( * @param wrappedIndex value used to derive a key */ actual fun deriveChild(wrappedIndex: BigIntegerWrapper): EdHDKey { - val derived = ed25519_bip32.derive_bytes(privateKey, chainCode, wrappedIndex.value.uintValue()); + val derived = ed25519_bip32.derive_bytes(privateKey, chainCode, wrappedIndex.value.uintValue()) return EdHDKey( privateKey = derived[0], diff --git a/apollo/src/jvmMain/kotlin/io/iohk/atala/prism/apollo/derivation/EdHDKey.kt b/apollo/src/jvmMain/kotlin/io/iohk/atala/prism/apollo/derivation/EdHDKey.kt index 052865dc2..68d68624d 100644 --- a/apollo/src/jvmMain/kotlin/io/iohk/atala/prism/apollo/derivation/EdHDKey.kt +++ b/apollo/src/jvmMain/kotlin/io/iohk/atala/prism/apollo/derivation/EdHDKey.kt @@ -11,7 +11,6 @@ import io.iohk.atala.prism.apollo.utils.ECConfig actual class EdHDKey actual constructor( actual val privateKey: ByteArray, actual val chainCode: ByteArray, - actual val publicKey: ByteArray?, actual val depth: Int, actual val index: BigIntegerWrapper ) { From 32a4889022f2ea279a47df51877759251b955926 Mon Sep 17 00:00:00 2001 From: Curtis Date: Wed, 15 May 2024 12:43:34 +0100 Subject: [PATCH 36/39] comments for convertSecretKeytoX25519 Co-authored-by: Ahmed Moussa --- .../io/iohk/atala/prism/apollo/utils/ConvertEd25519.kt | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/apollo/src/commonMain/kotlin/io/iohk/atala/prism/apollo/utils/ConvertEd25519.kt b/apollo/src/commonMain/kotlin/io/iohk/atala/prism/apollo/utils/ConvertEd25519.kt index ff315dcd3..8ead6d0bc 100644 --- a/apollo/src/commonMain/kotlin/io/iohk/atala/prism/apollo/utils/ConvertEd25519.kt +++ b/apollo/src/commonMain/kotlin/io/iohk/atala/prism/apollo/utils/ConvertEd25519.kt @@ -4,6 +4,13 @@ import org.kotlincrypto.hash.sha2.SHA512 import kotlin.experimental.and import kotlin.experimental.or +/** + * This function converts an Ed25519 secret key into a Curve25519 secret key. + * Curve25519 keys are used in the key exchange process to encrypt communications over networks. + * + * @param secretKey The Ed25519 secret key to be converted into a Curve25519 secret key. + * @return The Curve25519 key, which is a 32-byte hash derived from the original Ed25519 key. + */ fun convertSecretKeyToX25519(secretKey: ByteArray): ByteArray { // Hash the first 32 bytes of the Ed25519 secret key val hashed = SHA512().digest(secretKey.sliceArray(0 until 32)) From 0cb910580bde9e95ada82585d42c3a07244d9a2f Mon Sep 17 00:00:00 2001 From: Curtish Date: Wed, 15 May 2024 15:52:18 +0100 Subject: [PATCH 37/39] android test and workflow updates Signed-off-by: Curtis Harding --- .github/workflows/release-documentation.yml | 11 ++++++++++ .github/workflows/release.yml | 11 ++++++++++ .../prism/apollo/derivation/EdHDKeyTest.kt | 21 +++++++++++++++++++ .../prism/apollo/utils/ConvertEd25519.kt | 2 +- 4 files changed, 44 insertions(+), 1 deletion(-) create mode 100644 apollo/src/androidInstrumentedTest/kotlin/io/iohk/atala/prism/apollo/derivation/EdHDKeyTest.kt diff --git a/.github/workflows/release-documentation.yml b/.github/workflows/release-documentation.yml index 18eeb4c3f..4787c2567 100644 --- a/.github/workflows/release-documentation.yml +++ b/.github/workflows/release-documentation.yml @@ -56,6 +56,17 @@ jobs: run: | brew install autoconf automake libtool + - name: "Install rust toolchain (Linux)" + if: matrix.os-type == 'linux' + run: sudo apt install rustc build-essential -y + + - name: "Install rust toolchain (Macos)" + if: matrix.os-type == 'macos' + run: brew install rustup + + - name: "Install wasm-pack" + run: cargo install wasm-pack + - name: "Dokka Documentation Generation" run: | ./gradlew dokkaHtml diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 33b086d28..4b0538bf8 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -59,6 +59,17 @@ jobs: git_user_signingkey: true git_commit_gpgsign: true + - name: "Install rust toolchain (Linux)" + if: matrix.os-type == 'linux' + run: sudo apt install rustc build-essential -y + + - name: "Install rust toolchain (Macos)" + if: matrix.os-type == 'macos' + run: brew install rustup + + - name: "Install wasm-pack" + run: cargo install wasm-pack + - name: "Release" env: GIT_AUTHOR_EMAIL: ${{ steps.import_gpg.outputs.email }} diff --git a/apollo/src/androidInstrumentedTest/kotlin/io/iohk/atala/prism/apollo/derivation/EdHDKeyTest.kt b/apollo/src/androidInstrumentedTest/kotlin/io/iohk/atala/prism/apollo/derivation/EdHDKeyTest.kt new file mode 100644 index 000000000..8c52d31f7 --- /dev/null +++ b/apollo/src/androidInstrumentedTest/kotlin/io/iohk/atala/prism/apollo/derivation/EdHDKeyTest.kt @@ -0,0 +1,21 @@ +package io.iohk.atala.prism.apollo.derivation + +import io.iohk.atala.prism.apollo.utils.decodeHex +import io.iohk.atala.prism.apollo.utils.toHexString +import kotlin.test.Test +import kotlin.test.assertEquals + +@RunWith(AndroidJUnit4::class) +class EdHDKeyTest { + @Test + fun test_derive_m1() { + val privateKey = "f8a29231ee38d6c5bf715d5bac21c750577aa3798b22d79d65bf97d6fadea15adcd1ee1abdf78bd4be64731a12deb94d3671784112eb6f364b871851fd1c9a24".decodeHex() + val chainCode = "7384db9ad6003bbd08b3b1ddc0d07a597293ff85e961bf252b331262eddfad0d".decodeHex() + + val key = EdHDKey(privateKey, chainCode) + val derived = key.derive("m/1'") + + assertEquals(derived.privateKey.toHexString(), "4057eb6cab9000e3b6fe7e556341da1ca2f5dde0b689a7b58cb93f1902dfa15a5a10732ff348051c6e0865c62931d4a73fa8050b8ff543b43fc0000a7e2c5700") + assertEquals(derived.chainCode.toHexString(), "9a170f689c8b9b3502ee846f457ab3dd1b017cfb2cd68865c7f24dbabcbc2256") + } +} diff --git a/apollo/src/commonMain/kotlin/io/iohk/atala/prism/apollo/utils/ConvertEd25519.kt b/apollo/src/commonMain/kotlin/io/iohk/atala/prism/apollo/utils/ConvertEd25519.kt index 8ead6d0bc..f6e4b4846 100644 --- a/apollo/src/commonMain/kotlin/io/iohk/atala/prism/apollo/utils/ConvertEd25519.kt +++ b/apollo/src/commonMain/kotlin/io/iohk/atala/prism/apollo/utils/ConvertEd25519.kt @@ -5,7 +5,7 @@ import kotlin.experimental.and import kotlin.experimental.or /** - * This function converts an Ed25519 secret key into a Curve25519 secret key. + * This function converts an Ed25519 secret key into a Curve25519 secret key. * Curve25519 keys are used in the key exchange process to encrypt communications over networks. * * @param secretKey The Ed25519 secret key to be converted into a Curve25519 secret key. From 03571614348fbfb2dc56db546bae0f59c5e96ffb Mon Sep 17 00:00:00 2001 From: Curtish Date: Thu, 16 May 2024 09:46:13 +0100 Subject: [PATCH 38/39] rust-ed25519-bip32 submodule update Signed-off-by: Curtis Harding --- rust-ed25519-bip32 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-ed25519-bip32 b/rust-ed25519-bip32 index 975e9e608..58a9ec0c4 160000 --- a/rust-ed25519-bip32 +++ b/rust-ed25519-bip32 @@ -1 +1 @@ -Subproject commit 975e9e608ffe3d3e5095e32357056ed4bdfb9f54 +Subproject commit 58a9ec0c4f80ff9d33cc11fecdbd53ffb7a1285d From 298532eed1c2a86871325aaf71517b6c675e5161 Mon Sep 17 00:00:00 2001 From: Curtish Date: Wed, 22 May 2024 09:06:06 +0100 Subject: [PATCH 39/39] rust-ed25519-bip32 submodule update Signed-off-by: Curtis Harding --- .gitmodules | 2 +- rust-ed25519-bip32 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitmodules b/.gitmodules index 16bf8d3ee..477ea4dc0 100644 --- a/.gitmodules +++ b/.gitmodules @@ -6,4 +6,4 @@ [submodule "rust-ed25519-bip32"] path = rust-ed25519-bip32 url = https://github.com/input-output-hk/rust-ed25519-bip32.git - branch = rust-uniffi + branch = master diff --git a/rust-ed25519-bip32 b/rust-ed25519-bip32 index 58a9ec0c4..c7217751c 160000 --- a/rust-ed25519-bip32 +++ b/rust-ed25519-bip32 @@ -1 +1 @@ -Subproject commit 58a9ec0c4f80ff9d33cc11fecdbd53ffb7a1285d +Subproject commit c7217751c278c4ed0e6c26e3ef9d6d14195582b9