1
0
Fork
You've already forked unimo-sdk-java
0
No description
  • Java 100%
2026年06月12日 13:47:43 +02:00
conformance init 2026年06月08日 10:39:42 +02:00
gradle/wrapper Add JitPack publishing config, Gradle wrapper, and install docs 2026年06月08日 12:13:28 +02:00
src fix epoch bug 2026年06月12日 13:47:43 +02:00
.gitignore Add JitPack publishing config, Gradle wrapper, and install docs 2026年06月08日 12:13:28 +02:00
build.gradle Add JitPack publishing config, Gradle wrapper, and install docs 2026年06月08日 12:13:28 +02:00
gradlew Add JitPack publishing config, Gradle wrapper, and install docs 2026年06月08日 12:13:28 +02:00
gradlew.bat Add JitPack publishing config, Gradle wrapper, and install docs 2026年06月08日 12:13:28 +02:00
jitpack.yml Add JitPack publishing config, Gradle wrapper, and install docs 2026年06月08日 12:13:28 +02:00
LICENSE update license 2026年06月11日 07:31:42 +02:00
README.md Pin README JitPack version to v0.0.1 2026年06月08日 12:23:29 +02:00
settings.gradle init 2026年06月08日 10:39:42 +02:00

unimo-sdk-java

Release

Java/Android port of the TypeScript E2EE client SDK (sdk/ts). Post-quantum (ML-DSA-87 + ML-KEM-1024), cSHAKE256-derived identities, AES-256-GCM content encryption — wire-compatible with the gateway and the TS SDK.

Status

Phase Scope State
0 Scaffold + cross-language conformance harness done
1 crypto + shared (byte-exact interop foundation) done
2 Identity: Members, Validators, register/login, deriveKeys unlock, ApiClient (OkHttp) done — live-verified vs gateway (register→login→unlock)
3 VaultController: manifest CAS PUT/GET, member add/remove + key rotation, reauth done — live-verified (addMember+rotation, new-member login, reauth, removeMember)
4 Tasker: chunked storage upload/download + CAS done — live-verified (single + multi-chunk 8.4 MiB round-trips, CAS bump)
5 Collections/KV + ReactiveValue observable (dependency-free) done — live-verified (create/persist/reload + survives key rotation)
6a Billing + Invites (manager-area read/write) done — live-verified (create→claim→finalize→login; billing catalog/state)
6b WebSocket Connection (vault:event push) + minimal Account done — live-verified (real blob_put push received; Account upload/download)

Feature-complete vs the TypeScript SDK (the only TS gaps are also stubs there: VFS/LIST/CRDTLIST collection types, and the Tasker reactive task-queue/progress UI convenience).

Live coverage: 31/31 in IntegrationRunner (register/login/unlock · member add/remove + key rotation · reauth · single + multi-chunk encrypted storage + CAS · KV collection create/reload/rotate · billing catalog/state · full invite create→claim→finalize→login · WebSocket vault:event push · Account wrapper). Offline cross-language conformance: 45/45.

UI binding: ReactiveValue<T> is a neutral, dependency-free observable (get/set/update/subscribe/onChange). Adapt at the UI edge — MutableLiveData (rv.subscribe(ld::postValue)) for Views/Java, or MutableStateFlow (rv.subscribe { flow.value = it }, read via collectAsState()) for Compose. The core stays Android-free and pure-JVM-testable.

Dependencies (two)

  • org.bouncycastle:bcprov-jdk18on:1.81 — ML-DSA-87, ML-KEM-1024, cSHAKE256. Used via low-level APIs (no JCA provider registration) to avoid clashing with Android's bundled com.android.org.bouncycastle.
  • com.squareup.okhttp3:okhttp:4.12.0 — HTTP + WebSocket (Phase 2+).

Everything else is core JVM: AES-GCM/SHA-256 (javax.crypto/java.security), Base64/Hex (BouncyCastle encoders), JSON (hand-rolled shared/Json — canonical writer + parser), CompletableFuture for the async network surface.

Why not native PQC?

javax.crypto.KEM (JDK 21) is only a generic API; ML-KEM/ML-DSA implementations are JDK 24+ (SunJCE) and Android 17 (Keystore) only. Neither works here: cSHAKE256 has no native implementation in any JDK/Android provider, and the SDK requires seed-derived, exportable keypairs (recovery devices re-derive keys from a seed) — the opposite of Android Keystore's non-exportable, hardware-bound keys. BouncyCastle is the only fit.

Layout (mirrors sdk/ts/src_ts)

src/main/java/com/unimo/sdk/
├── crypto/ CryptoPQ (ML-DSA/ML-KEM), AEAD (AES-GCM), CryptoUtils (sha256, cSHAKE256,
│ derivations), SeedRandom (deterministic keygen), CodedException
├── shared/ Consts, Helpers (hex/base64/concat/u32be/chunkId), Json (canonical + parse)
└── client/ (Phase 2+)
conformance/ ConformanceRunner + vectors.json (golden oracle from the TS SDK)

Install (JitPack)

Published from this Codeberg repo via JitPack. Add the JitPack repository, then the dependency — BouncyCastle and OkHttp come in transitively.

Gradle

repositories {
 mavenCentral()
 maven { url 'https://jitpack.io' }
}
dependencies {
 implementation 'org.codeberg.thinking_tools:unimo-sdk-java:v0.0.1'
}

Maven

<repositories>
 <repository>
 <id>jitpack.io</id>
 <url>https://jitpack.io</url>
 </repository>
</repositories>
<dependency>
 <groupId>org.codeberg.thinking_tools</groupId>
 <artifactId>unimo-sdk-java</artifactId>
 <version>v0.0.1</version>
</dependency>

Any pushed tag, main-SNAPSHOT (latest commit), or a commit hash works as the version.

Build & test

# Gradle (consumer path)
gradle test
# No-Gradle path (what CI/dev can run with just a JDK): fetch the 4 compile jars into libs/
M=https://repo1.maven.org/maven2
curl -sLo libs/bcprov-jdk18on-1.81.jar $M/org/bouncycastle/bcprov-jdk18on/1.81/bcprov-jdk18on-1.81.jar
curl -sLo libs/okhttp-4.12.0.jar $M/com/squareup/okhttp3/okhttp/4.12.0/okhttp-4.12.0.jar
curl -sLo libs/okio-jvm-3.6.0.jar $M/com/squareup/okio/okio-jvm/3.6.0/okio-jvm-3.6.0.jar
curl -sLo libs/kotlin-stdlib-1.9.10.jar $M/org/jetbrains/kotlin/kotlin-stdlib/1.9.10/kotlin-stdlib-1.9.10.jar
CP=$(printf 'libs/%s:' bcprov-jdk18on-1.81.jar okhttp-4.12.0.jar okio-jvm-3.6.0.jar kotlin-stdlib-1.9.10.jar)
javac -cp "$CP" -d out $(find src/main/java -name '*.java') conformance/ConformanceRunner.java conformance/IntegrationRunner.java
java -cp "out:$CP" conformance.ConformanceRunner conformance/vectors.json
# Live end-to-end test (needs the `bun run dev:local` gateway up on :3000):
java -cp "out:$CP" conformance.IntegrationRunner http://localhost:3000

Conformance workflow

conformance/vectors.json is generated from the real noble/WebCrypto crypto:

bun run sdk/ts/tools/gen-conformance.ts # regenerate after any TS crypto change

The Java port must reproduce every vector byte-for-byte (keygen-from-seed public keys, cSHAKE outputs, canonical JSON, AEAD wire bytes, cross-language sign/verify + decapsulate).

Interop contract (verified)

  • ML-DSA-87: FIPS-204 pure, empty context (0x00‖0x00‖M), hedged signing. Sign the raw 32-byte SHA-256 digest of the canonical JSON; payloadHash = base64(digest).
  • ML-KEM-1024: FIPS-203; 64-byte seed = d‖z.
  • cSHAKE256: N="", S=personalization (SP 800-185).
  • AEAD: AES-256-GCM, [12B IV][ciphertext][16B tag].
  • Canonical JSON: recursive key sort + compact JSON.stringify.