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

# Stoffel Secret MPC Programming

> Build MPC apps with secret types, Share, ClientStore, Mpc, MpcOutput, and runnable private-input examples.

> Scope: AI-agent-agnostic playbook for building applications with the Stoffel framework. This is not a maintainer guide for compiler, VM, protocol, or release engineering work.
>
> Dependency assumption: use current public crates.io releases by default, then the official GitHub repository at a full immutable revision when the needed change is not published. A local checkout is a separate, explicitly requested, nonportable framework-development workflow.

## Use when

Use this playbook when an app handles private values, secret shares, client-provided inputs, MPC output delivery, protocol/runtime metadata, or secure algorithm examples.

## Goal

Help developers write MPC-oriented Stoffel apps using `secret` types, `Share.*`, `ClientStore.*`, `Mpc.*`, `MpcOutput.*`, and related builtins, while preserving runnable local examples.

For client-owned private input in a multi-user or networked application, the participant-owned process is the Stoffel MPC client and submits directly to the separately deployed MPC service. The application control plane must not receive or persist participant plaintext. Complete the trust-boundary worksheet in [Stoffel Full App Golden Path](/developer-skills/stoffel-full-app-golden-path), then use [Stoffel App Network and Off-Chain Integration](/developer-skills/stoffel-app-network-and-offchain-integration) for the production client path.

## Current source of truth

* `crates/stoffel-lang/examples/README.md`
* `crates/stoffel-lang/examples/COVERAGE.md`
* `crates/stoffel-lang/examples/mpc_*`
* `crates/stoffel-lang/examples/bits/secret/*`
* `crates/stoffel-lang/examples/matrix/secret/*`
* `crates/stoffel-lang/examples/polynomials/secret/*`
* `crates/stoffel-lang/examples/number_theory/secret/*`
* `crates/stoffel-lang/examples/avss_*`
* `crates/stoffel-lang/examples/threshold_signatures/*`

## Minimal secret app

```stfl theme={null}
def main(a: secret int64, b: secret int64) -> secret int64:
  return a + b
```

When run locally through the CLI/SDK, source/file programs returning a secret value may be wrapped/opened by the local execution path so app tests can assert clear outputs.

For client-owned private inputs, use `ClientStore` in the Stoffel program. The CLI flags below inject plaintext into one trusted local harness process for program testing; they do not define the production application-service path:

```stfl theme={null}
# run-args: --client-input 0=40 --client-input 1=2 --expected-output-clients 2

def main() -> None:
  var a: secret int64 = ClientStore.take_share(0, 0)
  var b: secret int64 = ClientStore.take_share(1, 0)
  var sum: secret int64 = a + b
  MpcOutput.send_to_client(0, [sum])
  MpcOutput.send_to_client(1, [sum])
```

The first argument to `ClientStore.take_share(client_slot, input_index)` is the client slot. The second is that client's ordered input index. Repeating `--client-input 0=...` appends inputs for slot `0` in order.

## Secret values and shares

Common patterns:

```stfl theme={null}
var x: secret int64 = Share.random()
var y = Share.from_clear_int(5, 1)
var sum: secret int64 = x + y
var product: secret int64 = x * y
var opened: int64 = sum.reveal()
```

Prefer `secret T` annotations when you know the share's scalar shape. The `secret` keyword belongs inside type annotations for parameters, return types, local variables, list elements, and object fields:

```stfl theme={null}
def score(raw: secret int64, weight: int64) -> secret int64:
  var scaled: secret int64 = raw * weight
  return scaled + 10
```

Do not use `secret` as a declaration modifier before `def` or `var`. Use `var x: secret int64 = ...`, not `secret var x = ...`.

Use normal arithmetic operators (`+`, `-`, `*`, `/`) for secret values when the operation fits the value shape. Method/function forms such as `Share.add`, `Share.mul`, `.add_scalar`, and `.mul_scalar` remain useful when you want to call a specific builtin explicitly.

For fixed-point client inputs:

```stfl theme={null}
var fixed: secret fix64 = ClientStore.take_share_fixed(0, 0)
```

For boolean circuits:

```stfl theme={null}
def gate_and(a: secret bool, b: secret bool) -> secret bool:
  return a * b

def gate_not(a: secret bool) -> secret bool:
  return 1 - a

def gate_or(a: secret bool, b: secret bool) -> secret bool:
  var ab: secret bool = gate_and(a, b)
  return a + b - ab

def gate_xor(a: secret bool, b: secret bool) -> secret bool:
  var ab: secret bool = gate_and(a, b)
  return a + b - (ab * 2)
```

## Client input shares

Use `ClientStore` when participant-owned SDK clients provide private inputs through the coordinator/client path. Each client owns and submits its complete ordered input vector directly; do not place `.with_client_input(...)`, plaintext client fields, or private payload proxies in an application backend:

```stfl theme={null}
var value = ClientStore.take_share(0, 0)
var fixed = ClientStore.take_share_fixed(0, 1)
var n_clients: int64 = ClientStore.get_number_clients()
var n_input_clients: int64 = ClientStore.get_number_input_clients()
var n_output_clients: int64 = ClientStore.get_number_output_clients()
```

CLI flags:

```sh theme={null}
stoffel run src/main.stfl \
  --client-input 0=42 --client-input 0=58 \
  --client-input 1=7 \
  --expected-output-clients 2
```

Input-file equivalents are documented in [Stoffel CLI App Workflow](/developer-skills/stoffel-cli-app-workflow). Treat CLI flags and input files as trusted local fixtures. They prove program semantics, not that a production control plane is outside the plaintext path.

## Client outputs

Send share outputs to clients when the runtime advertises that capability:

```stfl theme={null}
if Mpc.has_capability("client-output"):
  MpcOutput.send_to_client(0, [result_share])
```

Many current examples now document `--expected-output-clients N` in a first-line `# run-args:` header. Preserve that flag in local runs; without it, output-capable client slots may not be declared in the local runtime.

## Runtime metadata

Useful app metadata:

* `Mpc.party_id()`
* `Mpc.n_parties()`
* `Mpc.threshold()`
* `Mpc.instance_id()`
* `Mpc.protocol_name()`
* `Mpc.curve()` / `Mpc.field()`
* `Mpc.is_ready()`
* `Mpc.has_capability(name)`
* `Mpc.capabilities()`
* `Mpc.rand()` / `Mpc.rand_int()`

## Example families to inspect

MPC primitive examples:

* `mpc_share_arithmetic`
* `mpc_boolean_circuit`
* `mpc_bitwise_share`
* `mpc_random_bit`
* `mpc_bit_decomposition`
* `mpc_secure_comparison`
* `mpc_select_minmax`
* `mpc_aes128_circuit`
* `mpc_client_private_score`
* `mpc_client_federated_average`
* `mpc_protocol_coordination`
* `mpc_share_toolkit`

Secure algorithm examples with recent client I/O headers:

* Comparison and bit algorithms: `mpc_range_check`, `mpc_clamp`, `mpc_compare_family`, `mpc_is_zero`, `mpc_popcount_secret`, `mpc_msb_log2`, `mpc_lowest_set_bit`, `mpc_parity`, `mpc_bit_reverse_rotate`, `mpc_sign_extend`.
* Oblivious data access/search: `mpc_oblivious_read`, `mpc_oblivious_write`, `mpc_mux_tree`, `mpc_linear_search`, `mpc_lookup_table`, `mpc_pattern_match`.
* Arithmetic/number theory: `mpc_secure_division`, `mpc_modulo_secret`, `mpc_mod_constant`, `mpc_gcd`, `mpc_lcm`, `mpc_reciprocal`, `mpc_sqrt`, `mpc_horner_eval`, `mpc_secret_base_power`, `mpc_secret_exponentiation`, `mpc_modexp`, `mpc_modinv`, `mpc_transcendental`.
* Sorting/ranking/arrays: `mpc_bitonic_sort`, `mpc_secure_shuffle`, `mpc_top_k`, `mpc_rank_order`.

Gallery examples:

* `bits/secret/*`: private bit/boolean circuits with `ClientStore` inputs.
* `matrix/secret/*`: private matrix/vector and fixed-point examples.
* `polynomials/secret/*`: polynomial, interpolation, coding, and private matching examples.
* `number_theory/secret/*`: private GCD, modular inverse, CRT, MAC, equality, and Diophantine examples.

Advanced protocol/crypto examples:

* `avss_share_auditor`
* `avss_certificate/*`
* `threshold_signatures/*`

## Validation / done criteria

For a secret app source change:

```sh theme={null}
stoffel check path/to/main.stfl
stoffel build path/to/main.stfl
stoffel run path/to/main.stfl --timeout-secs 180 <documented run args>
```

For an example with a `# run-args:` header, use the exact flags from that header. Example:

```sh theme={null}
stoffel run crates/stoffel-lang/examples/mpc_bitonic_sort/main.stfl \
  --client-input 0=7 --client-input 0=3 --client-input 0=5 --client-input 0=1 \
  --client-input 0=8 --client-input 0=2 --client-input 0=6 --client-input 0=4 \
  --expected-output-clients 1 \
  --timeout-secs 180
```

Framework validation:

```sh theme={null}
cd /path/to/stoffel/crates/stoffel-lang
./examples/validate_examples.sh
```

## Common pitfalls

* Do not use clear function arguments when the program expects `ClientStore` inputs.
* Do not move client-owned `ClientStore` values into an application server or SDK server/node builder. Keep private input encoding and submission in each SDK client.
* Do not reorder repeated `--client-input` values for the same slot; order is the per-client input index.
* Do not omit `--expected-output-clients` for programs that call `MpcOutput.send_to_client` or `Share.send_to_client`.
* Do not reveal intermediate private values in examples unless the algorithm intentionally opens that result.
* Do not claim protocol behavior from static compilation alone; run local MPC or report the blocker.
