Skip to content

feat(kmp): sha256 / sha512 / hmac as KMP modules via kotlincrypto - #1202

Merged
bmc08gt merged 2 commits into
code/cashfrom
feat/kmp-hashing
Aug 7, 2026
Merged

feat(kmp): sha256 / sha512 / hmac as KMP modules via kotlincrypto#1202
bmc08gt merged 2 commits into
code/cashfrom
feat/kmp-hashing

Conversation

@bmc08gt

@bmc08gt bmc08gt commented Aug 7, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Converts :libs:encryption:sha256, :libs:encryption:sha512, and :libs:encryption:hmac to Kotlin Multiplatform modules following the pattern established by :libs:encryption:base58.
  • SHA-256 hashing backed by org.kotlincrypto.hash:sha2:0.7.0 (pure-Kotlin, byte-deterministic across targets).
  • HMAC-SHA-256 / HMAC-SHA-512 backed by org.kotlincrypto.macs:hmac-sha2:0.7.0.
  • PBKDF2-HMAC-SHA512 implemented in pure Kotlin (commonMain) using the kotlincrypto HMAC primitive — no separate PBKDF2 library exists on Maven Central.
  • JVM-only Sha256Hash helpers (newDigest(), toBigInteger(), of(File)) isolated to androidMain; all consumers compile unchanged.
  • commonTest includes NIST/RFC KAT vectors for each primitive; androidHostTest covers JVM-only helpers.
  • All three modules exported through :kmp:shared-core XCFramework.

Test plan

  • ./gradlew :libs:encryption:sha256:allTests — KATs pass (NIST FIPS 180-4 vectors)
  • ./gradlew :libs:encryption:sha512:allTests — KATs pass (RFC 6070 PBKDF2-HMAC-SHA512 vectors)
  • ./gradlew :libs:encryption:hmac:allTests — KATs pass (RFC 4231 HMAC-SHA-512/256 vectors)
  • ./gradlew :libs:encryption:sha256:compileKotlinIosSimulatorArm64 — iOS compiles
  • ./gradlew :libs:encryption:sha512:compileKotlinIosSimulatorArm64 — iOS compiles
  • ./gradlew :libs:encryption:hmac:compileKotlinIosSimulatorArm64 — iOS compiles
  • ./gradlew :kmp:shared-core:compileKotlinIosSimulatorArm64 — XCFramework target compiles
  • ./gradlew :apps:flipcash:app:assembleDebug — all KMP modules compile successfully within app build

@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
KMP library modules (com.android.kotlin.multiplatform.library + withHostTest {})
expose `testAndroidHostTest`, not the `testDebugUnitTest` that com.android.library
modules expose. The flipcashTestDebug aggregate only bucketed modules into
android (`testDebugUnitTest`) and pure-JVM (`test`), so once base58 became a KMP
module (#1201) it landed in the android bucket and the aggregate depended on a
non-existent `:libs:encryption:base58:testDebugUnitTest` — silently skipping /
breaking the base58 vector gate in the aggregate. This PR's sha256/sha512/hmac
KMP conversions would extend the same fault.

Add a kmpUnitTestModules list (base58 + sha256/sha512/hmac), exclude it from the
android bucket, exclude the testless :kmp:shared-core umbrella, and depend on
`testAndroidHostTest` for the KMP modules so their host tests run in the aggregate.

Verified: `./gradlew flipcashTestDebug --dry-run` resolves the full task graph
(exit 0) with the KMP host-test tasks wired in.
@bmc08gt
bmc08gt merged commit 4d90721 into code/cash Aug 7, 2026
2 of 3 checks passed
@bmc08gt
bmc08gt deleted the feat/kmp-hashing branch August 7, 2026 19:12
bmc08gt added a commit that referenced this pull request Aug 7, 2026
…compile gate (#1205)

* fix(kmp): restore Java interop for sha256/sha512 KMP modules

- Sha256Hash.bytes: internal → public val (restores cross-module Kotlin
  access and the auto-generated Java getBytes() accessor; removes now-
  redundant explicit getBytes() method that would clash with the getter)
- Sha256Hash companion functions: add @JvmStatic so Java callers can
  resolve hash(), hashTwice(), wrap(), wrapReversed(), of(), twiceOf()
  as static methods
- PBKDF2SHA512.derive: add @JvmStatic so Java callers can call
  PBKDF2SHA512.derive(...) from a static context
- MnemonicCode.java: replace Sha256Hash.newDigest() (an androidMain
  extension, not Java-callable) with an inline MessageDigest.getInstance
  call; Sha256Hash.hash() now resolves via @JvmStatic above

* ci: add cred-free compile-check job to catch KMP interop regressions

Adds a compile-check job that runs :apps:flipcash:app:compileDebugSources
before the flipcash-tests job. This task compiles all Kotlin/Java sources
but stops before processDebugGoogleServices, so it requires no secrets.

The missing gate is what allowed the KMP conversions in #1201 and #1202
to land on code/cash without surfacing the Java interop breaks (missing
@JvmStatic, internal visibility) — those were only caught by compiling
the full consumer graph, which CI never did without creds.
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