golden — golden-ratio Newton on the Niobium Fog
Not logged in

Working example of an end-to-end FHE app on the Niobium Fog — the server side runs on ciphertexts only; the client keeps its keys. Self-contained: sources, bench, and design notes all live in this directory. (See also ../ for the sibling fhe-messenger example.)

Compute φ = (1 + √5) / 2 to 10 digits entirely on encrypted data — an end-to-end smoke test for the Niobium Fog that exercises CKKS record/replay, hollow trace upload, and FHE decryption of a non-trivial iterative circuit.

What runs where

Binary Runs on Does
golden_twin anywhere (no OpenFHE) plain-double reference of the exact circuit expression tree
golden_client client keygen + encrypts y₀=0.45 and the public constants 5, 3, 0.5, 2.5
golden_server local sim or Fog records the Newton loop as a FHETCH trace, replays it
golden_decrypt client decrypts the result ciphertext and checks φ to N digits

The Fog never sees a plaintext: the client encrypts every value the server uses, recording runs in --hollow mode (the trace carries placeholder values, no real math on the worker), and the only decryption happens back at the client with the client's secret key.

The circuit

Newton's method for y = 1/√5, starting y₀ = 0.45:

y ← 0.5 · y · (3 − 5y²)        (3 iterations → ~1e-16 float error)
φ = 0.5 + 2.5y

~13 randomized ciphertext×ciphertext multiplies; no rotations, no bootstrap. Expression tree shared verbatim via circuit.h (templated over an op policy) so the floating-point twin and the CKKS server run the same arithmetic.

CKKS parameters

Ring 2048 for local gate testing, 65536 for the Fog. Depth 20 (naïve count 13 + headroom under FLEXIBLEAUTO), scaling 58, first modulus 60, HEStd_NotSet (demo posture; logQ fits comfortably at N=2^16).

Build

Needs a Release-built niobium-client checkout (this project compiles against the client's vendored instrumented OpenFHE + libnbfhetch):

# once: niobium-client Release build
(cd ../../niobium-client && make release)

cmake -B build -DCMAKE_BUILD_TYPE=Release   # -DNIOBIUM_CLIENT_DIR=<path> if not ../../niobium-client
cmake --build build -j

Build gotcha: every binary must be compiled with target_compile_definitions(... OPENFHE_CPROBES) (this project sets it). Without it the instrumented OpenFHE headers skip probe emission, the recorded trace is silently incomplete (~10k instructions short here, most keys unloaded) and replay reads uninitialized towers — opaque wrong answers or a Decode failure, not a build error. This repo's CMakeLists already handles the ordering quirk on Ubuntu (libnbfhetch must come after the OpenFHE libs on the link line because the instrumented OpenFHE libs need its cprobe symbols).

Run

Convenience targets (all run from build/):

make twin                # floating-point twin — bit-exact at this depth
make test-golden-local   # twin → client → server (record + replay) → decrypt at 10 digits
make fog-golden          # + Fog round trip (needs ~/.fog/credentials)

Manual equivalent of make test-golden-local:

cd build
./golden_twin
./golden_client golden_keys 2048
./golden_server golden_keys --no-ring-dim-check
./golden_decrypt golden_keys 10          # expect [PASS]

make fog-golden additionally re-keys at ring 65536, gates through the local simulator in hollow mode, then runs fog submit ./build/golden_server build/golden_fog --hollow --target=FOG and decrypts the ciphertext the Fog returns.

The server cache-name keys on ring dimension + iteration count (see cache_parameters in server.cpp), so the stale-toy-ring trace from the local gate is never shipped to the Fog (mixing them produces an opaque 19-second 500 from the worker). The Makefile also purges any prior trace project dir before recording — a leftover stale trace is silently reused otherwise.

Verified result

Fog job 695ea230…39 (fog-worker-batch-1, 2026-09-04): hollow trace 66,762 instructions, 206.6 MB uploaded (seven ciphertexts + eval mult key at N=2^16), worker run ~17 s, 1.0 MB returned. Decrypt of the Fog result: φ = 1.618033988748 — error 2.16e-12, a PASS with ~100× margin on the 10-digit bar.

Bench

bench/ holds the Fog round-trip benchmark harness: bash bench/fog_golden.sh [N] (or make bench-fog RUNS=N) runs N serial end-to-end round trips and writes bench/runs/<UTC-ts>/ with results.jsonl + REPORT.md (see bench/README.md). A verified 50/50 reference run lives there too; run dirs are not checked in.

See also

The sibling example ../fhe-messenger is an XMPP-shaped FHE maildrop (Rust CLI + C++ kernel) with its own architecture diagrams under its design/.

Provenance note

The source files of this example were generated by the Niobium FHE Application Design AI Assistant (FHEanna) and are BSD-3-Clause (see LICENSE); the underlying cryptography lives upstream in niobium-client (Apache-2.0) and its vendored OpenFHE build — compiling against it does not relicense any of that code.