Files
mpc/pkg/policy
zeekay 97e50fd5b6 sec(mpc): gate TFHE wallet keygen behind experimental_tfhe build tag
The threshold-FHE wallet keygen path (pkg/mpc/tfhe_session.go:154,165
production caller via pkg/mpc/node.go:583) was wired to
luxfi/threshold/protocols/tfhe.NewKeyGenerator + GenerateKeys. Per #197,
that primitive is a fail-loud placeholder: every party stores the full
master key, PartialDecrypt returns an HMAC tag, and CombineShares ignores
partials and runs single-party decryption. Upstream guards every entry
point with guardUnsafe() that panics unless
LUX_ALLOW_FAKE_TFHE_FOR_TESTING_ONLY=1 is set — by design.

Default production builds must not be able to reach the placeholder
primitive even with the env var set. Real-threshold wiring (luxfi/lattice
Shamir/LWE) is tracked as a multi-week separate task per LP-137 §2.6.

Changes:

- pkg/mpc/tfhe_session.go: //go:build experimental_tfhe — entire
  tfheKeygenSession + tfheComputeSession + TFHESession interface gated
  behind the tag.
- pkg/mpc/tfhe_node.go (new, experimental_tfhe): Node.CreateTFHEKeyGenSession
  + CreateTFHEComputeSession constructing the experimental sessions.
- pkg/mpc/tfhe_node_stub.go (new, !experimental_tfhe): stub Node methods
  that return ErrTFHENotImplemented from every entry point. This is what
  the production binary ships with.
- pkg/mpc/tfhe_errors.go (new, unconditional): ErrTFHENotImplemented
  symbol with a description pointing at LP-137 §2.6.
- pkg/mpc/node.go: removed the unconditional CreateTFHEKeyGenSession +
  CreateTFHEComputeSession definitions and the unused luxfi/fhe import.

Test pass:

  go test ./pkg/mpc/... ./pkg/policy/... -short -count=1 -race -timeout 60s
  ok  github.com/luxfi/mpc/pkg/mpc      2.016s
  ok  github.com/luxfi/mpc/pkg/policy   1.477s
  91 PASS, 0 FAIL (default build, no env var set)

  go build -o /tmp/mpcd_final ./cmd/mpcd/
  /tmp/mpcd_final version  # mpcd version 0.3.3 — no panic, no UNSAFE TFHE reach

  go build -tags experimental_tfhe ./pkg/mpc/...  # opt-in build OK

Note: pkg/policy/main_test.go sets LUX_ALLOW_FAKE_TFHE_FOR_TESTING_ONLY=1
because RealThresholdDecryptor's dispatcher tests exercise the placeholder
PartialDecrypter — same TestMain pattern threshold/protocols/tfhe uses.
These are orchestration-shape tests; they verify no threshold security
property because the underlying scheme has none.

Companion bumps required for the branch to compile:
- luxfi/threshold v1.6.0 -> v1.6.4 (FHECiphertext / FHEThresholdShare /
  ShareAggregator exports landed in v1.6.x)
- google/go-sev-guest -> go.mod (cc/attest/sev.go direct import)
- pkg/api/server.go: missing approval + tieredWallets fields added to
  satisfy in-tree handler references
2026-04-28 08:46:08 -07:00
..