> ## Documentation Index
> Fetch the complete documentation index at: https://docs.everabyte.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Java quickstart

> Encrypt files client-side in Java through the Everabyte Crypto SDK C ABI (Foreign Function & Memory API, Java 22+, or JNI) — a complete zero-knowledge round trip.

Java integrates through the SDK's **C ABI** (`include/evb_e2ee.h`). Two supported paths:

* **Java 22+ Foreign Function & Memory API (FFM)** — the recommended, JNI-free path (preview before 22; `--enable-preview` on 20/21).
* **JNI** — for older JVMs, wrap the same symbols with a thin JNI layer.

The native library is `libevb_e2ee_ffi` (built from `bindings/dart/rust` of [everabyte/crypto-sdk](https://github.com/everabyte/crypto-sdk), or fetched from GitHub Releases).

## 1. Install

```java theme={null}
// Load the shared library once (FFM):
Linker linker = Linker.nativeLinker();
SymbolLookup lib = SymbolLookup.libraryLookup("/path/to/libevb_e2ee_ffi.so", Arena.global());
// Convenience: symbols are also resolvable by name through linker.defaultLookup().
```

Declare the symbols you need (a subset — the full list is in the [C ABI reference](https://docs.everabyte.com/sdk/c-abi-reference.md)):

```java theme={null}
static final MethodHandle GENERATE_UMK = linker.downcallHandle(
    lib.lookup("evb_generate_umk").orElseThrow(),
    FunctionDescriptor.ofVoid(ADDRESS, JAVA_LONG, ADDRESS));

static final MethodHandle SEAL_ALL = linker.downcallHandle(
    lib.lookup("evb1_seal_all").orElseThrow(),
    FunctionDescriptor.of(JAVA_INT, ADDRESS, ADDRESS, ADDRESS, JAVA_LONG, ADDRESS, JAVA_LONG, ADDRESS));
```

## 2. Account key (UMK) — once, kept in your secret store

```java theme={null}
try (Arena arena = Arena.ofConfined()) {
    MemorySegment umk = arena.allocate(96);
    MemorySegment len = arena.allocate(JAVA_LONG);
    GENERATE_UMK.invoke(umk, 96L, len);

    // evb_umk_public_keys → JSON {publicKeyX25519, publicKeyMlkem} → POST /e2ee/keys/register
    // evb_wrap_umk_with_mnemonic(sk, seed, phrase, salt(16), nonce(12), blob, 8192)
    // → recovery blob; store it with the registration call.
}
```

The 96 UMK bytes never leave your JVM process; the Everabyte servers receive only public keys and wrapped blobs.

## 3. Encrypt → upload → attach envelope

```java theme={null}
byte[] dek = randomBytes(32);        // your CSPRNG — never persisted
byte[] fileNonce = randomBytes(12);
byte[] plaintext = Files.readAllBytes(Path.of("contract.pdf"));

try (Arena arena = Arena.ofConfined()) {
    MemorySegment pt = arena.allocateArray(JAVA_BYTE, plaintext);
    MemorySegment ct = arena.allocateArray(JAVA_BYTE, plaintext.length + 65536 + 16);
    MemorySegment ctLen = arena.allocate(JAVA_LONG);
    int rc = (int) SEAL_ALL.invoke(
        arena.allocateArray(JAVA_BYTE, dek),
        arena.allocateArray(JAVA_BYTE, fileNonce),
        pt, (long) plaintext.length,
        ct, (long) ct.byteSize(), ctLen);
    if (rc != 0) throw new IllegalStateException("seal failed: " + lastError(lib, arena));

    byte[] ciphertext = ct.asByteBuffer().limit((int) ctLen.get(JAVA_LONG, 0)).array();

    // wireName = evb_derive_wire_alias(...) → "evb-<hex64>"
    // encryptedName = evb_encrypt_file_name(dek, "contract.pdf", nonce12)
    // envelope = evb_wrap_dek_to_umk(dek, pkX25519, pkMlkem) → JSON
    //
    // POST /files/upload/{bucketId}  (multipart, filename = wireName)
    // POST /e2ee/files/by-path/envelope { bucketId, fileName, encryptedName, ...envelope }
}
```

On an attach timeout, reconcile whether it committed before cleanup. After a confirmed failure, resolve the uploaded row by bucket and opaque wire name, confirm it has no envelope, and hard-delete it through the file API as required by the E2EE upload contract. Handle retention blocks explicitly.

## 4. Download → decrypt

```java theme={null}
// GET /e2ee/files/{id}/envelope → envelope JSON
// GET /files/{id}/stream?download=true → stored ciphertext
// evb_unwrap_dek_from_umk(envelopeJson, sk, seed, out32, 32, len) → DEK
// evb1_open_all(dek, stored, len, out, cap, outLen) → ORIGINAL plaintext
// evb_decrypt_file_name(dek, encryptedName, out, cap, outLen) → real name
```

Error handling: every call returns `0` on success, negative otherwise; `evb_last_error(buf, cap)` returns the secret-free message (call with `cap = 0` first to get the required capacity).

## Next

* [C ABI reference](https://docs.everabyte.com/sdk/c-abi-reference.md) — every symbol, buffer convention and status code.
* [Node.js quickstart](https://docs.everabyte.com/sdk/quickstart-nodejs.md) — same round trip without a native library.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.