Skip to content

feat(kmp/ed25519): in-place KMP module (JNI on Android, cinterop on iOS) + mnemonic Kotlin rewrite - #1204

Merged
bmc08gt merged 8 commits into
code/cashfrom
feat/kmp-ed25519
Aug 10, 2026
Merged

feat(kmp/ed25519): in-place KMP module (JNI on Android, cinterop on iOS) + mnemonic Kotlin rewrite#1204
bmc08gt merged 8 commits into
code/cashfrom
feat/kmp-ed25519

Conversation

@bmc08gt

@bmc08gt bmc08gt commented Aug 7, 2026

Copy link
Copy Markdown
Collaborator

What changed

Why not in-place CMake in the KMP module?
`com.android.kotlin.multiplatform.library` (AGP 9.3.1) does not expose `externalNativeBuild` in its restricted DSL — the CMake/NDK build must live in a separate `com.android.library` module. The fallback path was taken as specified.

Files changed:

  • `libs/encryption/ed25519-kmp/` → `libs/encryption/ed25519/` (via `git mv`)
  • `libs/encryption/ed25519/` → `libs/encryption/ed25519-native/` (via `git mv`)
  • `libs/encryption/ed25519/build.gradle.kts` — updated C source path + namespace + `androidMain` dep
  • `libs/encryption/ed25519/cinterop/ed25519.def` — updated C header include path
  • `settings.gradle.kts` — replaced `ed25519-kmp` with `ed25519` + `ed25519-native` in includes and `kmpUnitTestModules`
  • `kmp/shared-core/build.gradle.kts` — updated `api`/`export` to `:libs:encryption:ed25519`

No consumer `build.gradle.kts` files needed changes.

Change B — Mnemonic Kotlin rewrite

`MnemonicCode.java` and `MnemonicException.java` replaced by Kotlin equivalents (cherry-picked from `origin/fix/kmp-consumer-compile`). The Java `main/java/` source files are deleted; Kotlin files land in `main/kotlin/`. Same package, same API surface.

Module map after this PR

Module Plugin Role
`:libs:encryption:ed25519` `com.android.kotlin.multiplatform.library` Public KMP API — `Ed25519Kmp` expect/actual
`:libs:encryption:ed25519-native` `flipcash.android.library` + CMake/NDK Internal JNI `.so`; `androidMain` only

Verification checklist

  • `:libs:encryption:ed25519:testAndroidHostTest` passes (ed25519.json gate)
  • `:libs:encryption:mnemonic:testDebugUnitTest` passes
  • `:apps:flipcash:app:compileDebugSources` succeeds (modulo GoogleServices)
  • `:kmp:shared-core:spmDevBuild` → XCFramework exports ed25519
  • `grep -r "ed25519-kmp"` returns empty

@github-actions github-actions Bot added type: feature New functionality area: crypto Solana, keys, encryption, signing area: build-system Gradle, convention plugins, build-logic labels Aug 7, 2026
@bmc08gt bmc08gt changed the title feat(kmp): ed25519-kmp — cinterop iOS actual + JNI Android actual (B1) feat(kmp): ed25519-kmp — cinterop iOS actual + JNI Android actual Aug 7, 2026
@bmc08gt bmc08gt changed the title feat(kmp): ed25519-kmp — cinterop iOS actual + JNI Android actual feat(kmp/ed25519): drop -kmp suffix — in-place KMP module (JNI on Android, cinterop on iOS) + mnemonic Kotlin rewrite Aug 7, 2026
@bmc08gt bmc08gt changed the title feat(kmp/ed25519): drop -kmp suffix — in-place KMP module (JNI on Android, cinterop on iOS) + mnemonic Kotlin rewrite feat(kmp/ed25519): in-place KMP module (JNI on Android, cinterop on iOS) + mnemonic Kotlin rewrite Aug 7, 2026
bmc08gt added 3 commits August 7, 2026 17:04
…ual (B1)

- New KMP module :libs:encryption:ed25519-kmp exposing Ed25519Kmp
  (createKeyPair, sign, verify, onCurve) to commonMain via expect/actual
- iosMain actual: Kotlin/Native cinterop to vendored orlp/ed25519 C sources;
  per-target static archive compiled via Gradle Exec task
- androidMain actual: delegates to existing com.getcode.ed25519.Ed25519 JNI
- commonTest: RFC 8032 vector gate reads ed25519.json on Android host + iOS
- Wires into :kmp:shared-core (api + export in SharedCore XCFramework)
- Existing :libs:encryption:ed25519 (JNI + CMake) left untouched
- Replace android.util.Base64 with java.util.Base64 so androidHostTest
  runs on JVM without Android stubs
- Add macOS arm64 dylibs (libnative-lib.dylib, libed25519.dylib) to
  androidHostTest/jniLibs so the JNI native-lib can load in host tests
- Use definitionFile (non-deprecated) instead of defFile in cinterop DSL
- Enable kotlin.mpp.enableCInteropCommonization in gradle.properties
- Rename :libs:encryption:ed25519-kmp → :libs:encryption:ed25519
  (KMP module takes the clean name; no -kmp suffix exposed to consumers)
- Rename :libs:encryption:ed25519 → :libs:encryption:ed25519-native
  (JNI/CMake module becomes an internal impl detail; androidMain delegates to it)
- Update cinterop path in ed25519.def and C source reference in build.gradle.kts
- Update kmpUnitTestModules and settings.gradle.kts registrations
- Update :kmp:shared-core api/export references
- Convert MnemonicCode and MnemonicException from Java to Kotlin
  (cherry-picked from origin/fix/kmp-consumer-compile)
@bmc08gt
bmc08gt requested a review from jeffyanta as a code owner August 7, 2026 21:36
@bmc08gt
bmc08gt removed the request for review from jeffyanta August 7, 2026 21:36
@bmc08gt bmc08gt self-assigned this Aug 7, 2026
bmc08gt added 3 commits August 8, 2026 10:27
…ude ed25519 JNI host test on Linux

- compileDebugSources transitively needs processDebugGoogleServices; write a dummy
  google-services.json (pkg com.flipcash.app.android) so the credless gate can build.
- ed25519's androidHostTest is a JNI vector test needing a host-native lib; it can't
  run on the Linux CI runner. Exclude it from CI unit tests (kmpUnitTestModules +
  noUnitTestModules); ed25519.json parity stays gated via the iOS cinterop path.
@bmc08gt
bmc08gt merged commit 1242e9b into code/cash Aug 10, 2026
3 checks passed
@bmc08gt
bmc08gt deleted the feat/kmp-ed25519 branch August 10, 2026 23:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: build-system Gradle, convention plugins, build-logic area: crypto Solana, keys, encryption, signing type: feature New functionality

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant