> ## 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.

# Rust quickstart

> Use the evb-e2ee-core crate to encrypt files client-side in Rust services and CLI tools, and store them zero-knowledge on Everabyte.

The Rust crate is the heart of the SDK: the TypeScript and Dart bindings are generated from it. Use it directly in services, CLI tools and agents where a native dependency is fine.

## 1. Get the crate

The public repository is [everabyte/crypto-sdk](https://github.com/everabyte/crypto-sdk) — a Cargo workspace, so a git dependency resolves the crate directly:

```toml theme={null}
[dependencies]
evb-e2ee-core = { git = "https://github.com/everabyte/crypto-sdk.git" }
```

Pin a tag for reproducible builds (`git = "…", tag = "v0.1.0"`). A local checkout works too: `path = "../crypto-sdk/core"`.

## 2. Generate the account key (UMK)

```rust theme={null}
use evb_e2ee_core::{keys, wrap, content, names};

// 96 bytes: 32-byte X25519 secret || 64-byte ML-KEM-768 seed.
let umk = wrap::generate_umk();
let public = umk.public()?; // { public_key_x25519: [u8;32], public_key_mlkem: [u8;1184] }
```

Seal it under a recovery phrase (BIP-39, Argon2id m=64 MiB / t=2 / p=1) and register the chain with the REST API exactly as in the [TypeScript quickstart](https://docs.everabyte.com/sdk/quickstart-typescript.md#2-generate-the-account-key-umk-once-on-your-machine) (same endpoints, same JSON):

```rust theme={null}
let phrase = obtain_fresh_bip39_phrase_from_your_recovery_ui(); // never hard-code a test phrase
let salt: [u8; 16] = rand::random();
let nonce: [u8; 12] = rand::random();
let mnemonic_blob = wrap::wrap_umk_with_mnemonic(&umk, phrase, &salt, &nonce)?;
// POST /e2ee/keys/register { publicKeyX25519, publicKeyMlkem, wraps: [{ wrapKind: "mnemonic", wrappedBlob }] }
```

## 3. Encrypt a file

```rust theme={null}
let plaintext = std::fs::read("contract.pdf")?;

let dek = keys::generate_dek();                       // [u8;32] — per-file, never persisted
let file_nonce: [u8; 12] = rand::random();

// EVB1 chunked AES-256-GCM (64 KiB authenticated chunks).
let payload = content::seal_all(&dek, &file_nonce, &plaintext)?;

// Opaque wire alias + encrypted display name.
let wire_name = names::derive_wire_alias(&umk, "contract.pdf")?;      // "evb-<hex64>"
let name_nonce: [u8; 12] = rand::random();
let encrypted_name = names::encrypt_file_name(&dek, "contract.pdf", &name_nonce)?;

// Wrap the DEK to the account key — HPKE v2 (RFC 9180 PSK, X25519 + ML-KEM-768).
let envelope = wrap::wrap_dek_to_umk(&dek, &public)?;                 // serde JSON, v: 2
let envelope_json = serde_json::to_string(&envelope)?;
```

## 4. Upload ciphertext, attach the envelope

```rust theme={null}
// POST /files/upload/{bucketId}  (multipart) — file part named `wire_name`
// POST /e2ee/files/by-path/envelope { bucketId, fileName: wire_name, encryptedName, ..envelope }
```

If envelope attachment times out, reconcile whether it committed before cleanup; a timeout may happen after the server stores the envelope. 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.

## 5. Download and decrypt

```rust theme={null}
// GET /e2ee/files/{fileId}/envelope  → envelope JSON
// GET /files/{fileId}/stream?download=true → stored ciphertext
let dek_back = wrap::unwrap_dek_from_umk_json(&envelope_json, &umk)?;
let original = content::open_all(&dek_back, &stored_ciphertext)?;
assert_eq!(original, plaintext);
let real_name = names::decrypt_file_name(&dek_back, &encrypted_name_b64)?;
```

## Streaming large files

`seal_all`/`open_all` are whole-buffer helpers: they accept and return the complete plaintext/ciphertext in memory. For large objects, use the streaming API, which processes at most one chunk at a time:

```rust theme={null}
let mut enc = content::Encryptor::new(&dek)?;
for chunk in read_in_64k_chunks("contract.pdf") {
    let block = enc.push(&chunk)?;   // returns the authenticated block
    write_to_pipe(&block);
}
let tail = enc.finish()?;            // final block (may be empty plaintext)
```

Decryption mirrors it with `content::Decryptor`. DEK material is zeroized on drop; nothing secret is logged.

## Next steps

* [Wire protocol reference](https://docs.everabyte.com/sdk/protocol-reference.md) — the full `evb-e2ee-v1` specification.
* [SDK API reference](https://docs.everabyte.com/sdk/api-reference.md) — every public function, including link-key and invite wraps for sharing.


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