Skip to main content

Native backend

NativeBackend (src/native-backend.ts) is a Node-only thin wrapper that shells out to the compiled ecdsa-spartan2 Rust CLI. Use it when:

  • you want to run prepare setup / show setup (the WASM bridge cannot do setup);
  • you have proving keys too large for browser memory (≥ 258 MB for the 1k variant);
  • you need parity with the CI / benchmark pipeline that lives under wallet-unit-poc/ecdsa-spartan2/.

It is not loaded by OpenAC.init and adds no dependencies for browser bundles — import the class directly:

import { NativeBackend } from "openac-sdk";

const native = new NativeBackend({ workDir: "wallet-unit-poc/ecdsa-spartan2" });

If binaryPath or workDir are omitted, NativeBackend searches relative paths from the SDK install location and process.cwd(). It throws SetupError("KEYS_NOT_FOUND") when neither resolves.

Configuration

FieldTypeDefaultDescription
binaryPathstringFirst match of target/release/ecdsa-spartan2 near the SDK or in cwd().Absolute path to the compiled CLI binary.
workDirstringFirst directory containing Cargo.toml near the SDK or in cwd().Directory the CLI runs in (keys, artifacts and inputs are resolved relative to it).
inputDirstring${workDir}/../circom/inputsWhere the input JSONs live (jwt/<size>/default.json, show/default.json).
envRecord<string, string>RUST_LOG=info plus auto-detected DYLD_LIBRARY_PATH for the witnesscalc dylib.Extra env vars merged into the child process.

Lifecycle

const native = new NativeBackend();

await native.setup("wallet-unit-poc/circom/inputs/jwt/1k/default.json");
await native.proveAll(
"wallet-unit-poc/circom/inputs/jwt/1k/default.json",
"wallet-unit-poc/circom/inputs/show/default.json",
);
const { valid } = await native.verifyPrepare();
MethodCLI command runDefault timeoutNotes
setupPrepare(inputPath?)prepare setup20 minWrites keys/prepare_*.key.
setupShow(inputPath?)show setup10 minWrites keys/show_*.key.
setup(inputPath?)both30 minConvenience for one-shot setup.
provePrepare(inputPath?)prepare prove5 minReads prepare_proving.key, writes prepare_proof.bin, prepare_instance.bin, prepare_witness.bin.
proveShow(inputPath?)show prove2 minReads show_proving.key, writes show_* artifacts.
generateSharedBlinds()generate_shared_blinds10 minWrites keys/shared_blinds.bin.
reblindPrepare() / reblindShow()prepare reblind / show reblind5 min / 2 minApplies the shared blinds.
verifyPrepare() / verifyShow()prepare verify / show verify10 minReturns { valid, output } based on a substring check for "Verification successful".
runBenchmark(inputPath?)benchmark30 minCaptures stdout/stderr for the benchmark harness.
proveAll(jwtInputPath?, showInputPath?)composite of the aboveinheritedgenerate_shared_blinds → prove prepare → reblind prepare → prove show → reblind show.

Artifacts

NativeBackend.loadKeys() reads the four *.key files into a KeySet compatible with OpenAC.precompute / OpenAC.present. loadProofs() returns the proof, instance, witness, and shared-blind bytes — useful for transporting Rust-generated artifacts into the WASM verifier.

saveArtifact(filename, data) / loadArtifact(filename) are escape hatches for custom file layouts; they read and write under ${workDir}/keys/.

The keysExist and proofsExist getters do a non-throwing existence check before attempting a CLI command.

Errors

FailureThrown
Binary or workDir not found at construction timeSetupError("KEYS_NOT_FOUND")
Non-zero exit from any CLI invocationProofError("PROOF_GENERATION_FAILED") with cause set to the underlying execFile error.

The output field on verifyPrepare() / verifyShow() returns the combined stdout+stderr; the CLI prints Verification successful on success, which is the substring NativeBackend looks for.