Skip to content

feat(kmp): add a jvm() target to the shared KMP libraries - #1838

Closed
bmc08gt wants to merge 3 commits into
code/cashfrom
feat/desktop-spike
Closed

bmc08gt wants to merge 3 commits into
code/cashfrom
feat/desktop-spike

Conversation

@bmc08gt

@bmc08gt bmc08gt commented Oct 23, 2026 •

Copy link
Copy Markdown
Collaborator

A Compose Desktop jvm() target can only depend on the shared KMP libraries once they build for the JVM, and none of the 14 did.

What changed

  • flipcash.kmp.library now declares every target: android (compileSdk and minSdk from the catalog), the five Apple natives, and jvm(). All 14 modules apply it instead of the raw plugins, and their build files keep only the namespace, test opt-ins, and module-specific wiring. shared-core hangs its SharedCore framework off targets.withType<KotlinNativeTarget>(), so KMMBridge publishing is otherwise unchanged.
  • sha512: the derivePlatform JVM actual reuses the Android JCA path, since the JDK ships PBKDF2WithHmacSHA512.
  • ed25519: the JVM actual is pure Java on net.i2p.crypto:eddsa, the library behind the test-utils shadow. The private key it returns is eddsa's clamped hash h, which is the orlp 64-byte layout the JNI and cinterop actuals use. The RFC 8032 vectors in ed25519.json pass on jvmTest, so desktop doesn't load the C library.

Modules that needed more than the target

  • ed25519 and sha512: the two new actuals above.
  • discrete-curve hard-coded compileSdk = 37. It now uses the catalog value, which adds minor API level 2.
  • kikcode compiles for jvm as is. KikCodePainter stays androidMain-only.
  • chat-cipher needed nothing: the libsodium bindings load on the JVM host, and its vectors pass on jvmTest.

The sha3 question in sign.c

sign.c includes sha3.h, but that header declares sha512_*, and sha3.c is libtom's SHA-512 with the 0x428a2f98d728ae22 round constant. sha512.c holds only the license comment, and sha512.h is empty. So it's a misnamed file, not SHA-3, which is why standard SHA-512 on the JVM reproduces the native signatures.

All 14 KMP library modules repeated the same android compileSdk/minSdk
block and the same five Apple targets, and only text-format applied the
convention plugin. The plugin now declares those targets, and every module
applies it and keeps only its namespace and test opt-ins.

shared-core attaches its SharedCore framework to each native target via
targets.withType<KotlinNativeTarget>() instead of a local target list.
discrete-curve hard-coded compileSdk = 37; it now picks up the catalog's
37 with minor API level 2 like the other modules.
First step of the desktop client: the KMP libraries need a JVM target
before Compose Desktop modules can depend on them. flipcash.kmp.library
now declares jvm() with jvmTarget from the android-java catalog version.

Two expect declarations needed JVM actuals:

- sha512 derivePlatform: the JDK ships PBKDF2WithHmacSHA512, so the
  actual is the Android JCA one with the same ASCII-only guard.
- Ed25519Kmp: pure Java on net.i2p.crypto:eddsa, which already backs the
  test-utils shadow. The 64-byte private key is eddsa's clamped hash `h`,
  the same orlp layout the JNI and cinterop actuals return, so keys move
  between platforms unchanged. The RFC 8032 vectors in ed25519.json pass
  on jvmTest, so no native library is loaded on desktop.

sign.c includes sha3.h, but that header declares the sha512_* functions
and sha3.c is libtom's SHA-512 (it carries the 0x428a2f98d728ae22 round
constant). It's a misnamed file, not SHA-3, which is why standard
SHA-512 on the JVM reproduces the native signatures.
@bmc08gt bmc08gt self-assigned this Oct 23, 2026
@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 Oct 23, 2026
Hilt's Gradle plugin rejects the AGP KMP android target, so KMP modules
run the Hilt KSP processors through kspAndroid without the plugin. Only
the app and notifications use @androidentrypoint, which is what the
plugin's bytecode rewrite exists for.

libs:coroutines moves onto the plugin, and its test fixtures become a
:libs:coroutines:test-fixtures module, since the KMP android target has
no testFixtures. shared:funding moves its sources to androidMain as the
first Hilt-bearing module on the KMP plugin.
@bmc08gt

bmc08gt commented Oct 30, 2026

Copy link
Copy Markdown
Collaborator Author

Landed in #1894 as one squash against code/cash.

@bmc08gt bmc08gt closed this Oct 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: auth Login, session, access keys, identity area: build-system Gradle, convention plugins, build-logic area: crypto Solana, keys, encryption, signing area: session type: feature New functionality

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant