Files
thakares 0ed3cb444d Refactor attestation engine and synchronize project documentation
- Refine session and storage lifecycle handling
- Improve VM extension architecture across server, shared, and WASM runtimes
- Enhance synthetic gene mutation engine integration and parity guarantees
- Align deterministic state progression between server and browser execution paths
- Update configuration examples and deployment guidance
- Expand architecture, API, threat model, privacy, and WASM build documentation
- Refresh README with comprehensive project overview, operational workflows,
  browser integration details, storage backend documentation, and security model
- Document v0.6.0 refactoring outcomes and design rationale
- Improve consistency across documentation, configuration, and implementation

This commit consolidates the v0.6.0 architectural refactoring effort,
strengthening deterministic browser/server parity while improving
maintainability, operational clarity, and project documentation.
2026-05-29 21:55:08 +05:30

164 lines
4.4 KiB
Markdown

# ChronoSeal WASM Build Guide
ChronoSeal uses a Rust-generated WASM package for browser-side attestation. The package is built from `wasm/` and copied into `frontend/pkg`.
## Responsibilities
The WASM runtime:
- generates a browser-local Ed25519 keypair
- signs canonical heartbeat payloads
- computes Blake3 hash-chain progression
- executes server-issued VM opcode programs
- initializes synthetic gene state
- previews gene mutation commitments
- commits or discards preview state after heartbeat response
The WASM runtime is not treated as a secure enclave. The server independently recomputes deterministic state.
## Requirements
```bash
rustup target add wasm32-unknown-unknown
cargo install wasm-pack
```
Verify:
```bash
wasm-pack --version
```
## Build
From the repository root:
```bash
wasm-pack build wasm --target web --release
rm -rf frontend/pkg
mv wasm/pkg frontend/pkg
```
`--target web` emits native ES modules compatible with the static frontend.
Development build:
```bash
wasm-pack build wasm --target web
rm -rf frontend/pkg
mv wasm/pkg frontend/pkg
```
Full project build:
```bash
bash scripts/build.sh
```
## Output Files
The package name comes from the crate name `chronoseal-wasm`, so generated files use the `chronoseal_wasm` prefix.
Expected `frontend/pkg/` contents include:
- `chronoseal_wasm.js`
- `chronoseal_wasm_bg.wasm`
- `chronoseal_wasm.d.ts`
- `package.json`
Generated files in `wasm/pkg/` and `frontend/pkg/` are build artifacts and should be regenerated during release.
## Browser Import
```js
import init, {
generate_keypair,
get_public_key,
sign_message,
compute_next_hash,
run_program,
init_gene_state,
preview_gene_commitment,
commit_gene_preview,
discard_gene_preview,
current_gene_commitment
} from './pkg/chronoseal_wasm.js';
```
Call `await init()` before using any exported function.
## Exported Functions
| Function | Signature | Failure value |
|---|---|---|
| `generate_keypair()` | `() -> string` | `""` only on unexpected failure |
| `get_public_key()` | `() -> string` | `""` if no keypair exists |
| `sign_message(msg)` | `(string) -> string` | `""` if no keypair exists or signing fails |
| `compute_next_hash(prev, ts, entropy, stack, salt)` | `(string, u64, string, string, string) -> string` | panic/error path should be avoided by valid inputs |
| `run_program(b64)` | `(string) -> JsValue` | returns empty/default stack state on invalid execution path |
| `init_gene_state(gene_size)` | `(u32) -> bool` | `false` |
| `preview_gene_commitment(order_b64, session_id, mutation_step, rounds)` | `(string, string, u64, u8) -> string` | `""` |
| `commit_gene_preview()` | `() -> bool` | `false` |
| `discard_gene_preview()` | `() -> void` | none |
| `current_gene_commitment(session_id, mutation_step)` | `(string, u64) -> string` | `""` if no committed state exists |
`rounds = 0` in `preview_gene_commitment` selects the shared default mutation round count.
## Mutation State Lifecycle
The browser must keep two gene states:
- committed state: the last accepted state
- preview state: candidate state for the heartbeat currently being sent
Expected sequence:
1. Call `init_gene_state(gene_size)` after `/init`.
2. Call `preview_gene_commitment(order_b64, session_id, mutation_step, rounds)` before signing `/hb`.
3. Include the returned commitment and mutation step in the signed heartbeat.
4. If the response contains next-state fields, call `commit_gene_preview()`.
5. If the heartbeat is rejected or errors, call `discard_gene_preview()`.
Never commit preview state before the server accepts the heartbeat.
## Hash-Chain Ordering
After an accepted heartbeat, compute the next local hash with the salt that was active when the heartbeat was sent. Then replace the local salt with `next_salt`.
Correct order:
```js
const sentSalt = currentSalt;
currentSalt = resp.next_salt;
prevHash = compute_next_hash(prevHash, timestamp, entropyJson, stackStateJson, sentSalt);
```
This mirrors the server, which computes and stores the new hash before rotating to the next salt.
## Serving WASM
The `.wasm` file must be served with:
```text
Content-Type: application/wasm
```
ChronoSeal's built-in static file service handles this for normal deployments.
## Validation
Recommended checks after WASM changes:
```bash
cargo test --workspace
cargo clippy --workspace --all-targets -- -D warnings
wasm-pack build wasm --target web
```
Then refresh `frontend/pkg`:
```bash
rm -rf frontend/pkg
mv wasm/pkg frontend/pkg
```