mirror of
https://github.com/luxfi/mpc.git
synced 2026-09-24 00:26:24 +00:00
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
This commit is contained in:
@@ -34,7 +34,7 @@ require (
|
||||
github.com/luxfi/hsm v1.1.2
|
||||
github.com/luxfi/log v1.4.1
|
||||
github.com/luxfi/metric v1.5.1
|
||||
github.com/luxfi/threshold v1.6.0
|
||||
github.com/luxfi/threshold v1.6.4
|
||||
github.com/luxfi/zap v0.2.0
|
||||
github.com/minio/minio-go/v7 v7.0.99
|
||||
github.com/mitchellh/mapstructure v1.5.0
|
||||
@@ -111,6 +111,8 @@ require (
|
||||
github.com/golang/mock v1.6.0 // indirect
|
||||
github.com/google/flatbuffers v25.12.19+incompatible // indirect
|
||||
github.com/google/go-cmp v0.7.0 // indirect
|
||||
github.com/google/go-sev-guest v0.14.1 // indirect
|
||||
github.com/google/logger v1.1.1 // indirect
|
||||
github.com/google/s2a-go v0.1.9 // indirect
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.3.14 // indirect
|
||||
github.com/googleapis/gax-go/v2 v2.21.0 // indirect
|
||||
@@ -204,6 +206,7 @@ require (
|
||||
go.temporal.io/sdk v1.41.1 // indirect
|
||||
go.uber.org/atomic v1.11.0 // indirect
|
||||
go.uber.org/mock v0.6.0 // indirect
|
||||
go.uber.org/multierr v1.11.0 // indirect
|
||||
go.yaml.in/yaml/v2 v2.4.4 // indirect
|
||||
go.yaml.in/yaml/v3 v3.0.4 // indirect
|
||||
golang.org/x/exp v0.0.0-20260312153236-7ab1446f8b90 // indirect
|
||||
|
||||
@@ -55,6 +55,8 @@ github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuy
|
||||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=
|
||||
github.com/ansel1/merry v1.8.1/go.mod h1:wJVu1mHEtEUWq5zTTX9RiWjcE+xL8y7BGYl2VTYdP7M=
|
||||
github.com/ansel1/merry/v2 v2.2.2/go.mod h1:sludwzkWfhZHOF4jSOViv+t2nnu2HNmtsMKzAfwmVB8=
|
||||
github.com/armon/go-metrics v0.4.1 h1:hR91U9KYmb6bLBYLQjyM+3j+rcd/UhE+G78SFnF8gJA=
|
||||
github.com/armon/go-metrics v0.4.1/go.mod h1:E6amYzXo6aW1tqzoZGT755KkbgrJsSdpwZ+3JqfkOG4=
|
||||
github.com/asaskevich/govalidator v0.0.0-20200108200545-475eaeb16496/go.mod h1:oGkLhpf+kjZl6xBf758TQhh5XrAeiJv/7FRz/2spLIg=
|
||||
@@ -239,6 +241,8 @@ github.com/google/go-configfs-tsm v0.2.2/go.mod h1:EL1GTDFMb5PZQWDviGfZV9n87WeGT
|
||||
github.com/google/go-sev-guest v0.14.1 h1:j/DXy9jk1qSW/dEV9vDiQnhAVFD1zqnWNVu6p1J0Jgo=
|
||||
github.com/google/go-sev-guest v0.14.1/go.mod h1:SK9vW+uyfuzYdVN0m8BShL3OQCtXZe/JPF7ZkpD3760=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/logger v1.1.1 h1:+6Z2geNxc9G+4D4oDO9njjjn2d0wN5d7uOo0vOIW1NQ=
|
||||
github.com/google/logger v1.1.1/go.mod h1:BkeJZ+1FhQ+/d087r4dzojEg1u2ZX+ZqG1jTUrLM+zQ=
|
||||
github.com/google/pprof v0.0.0-20260302011040-a15ffb7f9dcc h1:VBbFa1lDYWEeV5FZKUiYKYT0VxCp9twUmmaq9eb8sXw=
|
||||
github.com/google/pprof v0.0.0-20260302011040-a15ffb7f9dcc/go.mod h1:MxpfABSjhmINe3F1It9d+8exIHFvUqtLIRCdOGNXqiI=
|
||||
github.com/google/s2a-go v0.1.9 h1:LGD7gtMgezd8a/Xak7mEWL0PjoTQFvpRudN895yqKW0=
|
||||
@@ -370,8 +374,8 @@ github.com/luxfi/crypto v1.17.45 h1:uGK0y4+aLipE/M0YIQ5hcsWv0ZG0E4cPv03a94K/eLE=
|
||||
github.com/luxfi/crypto v1.17.45/go.mod h1:GnAkhQ7HNs3X0Tzx5nOONS3kl0yRmWHbDcRO5ffILsg=
|
||||
github.com/luxfi/database v1.17.44 h1:hfiTls7sqbweW+o4iaZqB8P997paC+vpgWmhN6v5MJ0=
|
||||
github.com/luxfi/database v1.17.44/go.mod h1:6Ey5y3I0WNLHbxIlIdFqUuKfBg+b0fAgTA8FgRgQ8zg=
|
||||
github.com/luxfi/edwards25519 v0.1.0 h1:zuSrBtgV4NUiJ8dzzJiLU4o+A0AHGnztRLUvZ24mAYk=
|
||||
github.com/luxfi/edwards25519 v0.1.0/go.mod h1:tFuuyXvI+xqUoHz9pwC+kqsALCGHSO1SymL1NjCOmFM=
|
||||
github.com/luxfi/edwards25519 v0.1.0 h1:YPoT831TZMslvNyy/KuTtpHi4BGZWgpwak06RCaYLzo=
|
||||
github.com/luxfi/edwards25519 v0.1.0/go.mod h1:MBoV+bPEz1tSMADPMSUaYdZ+agY3syG8B6z7RmJBH0A=
|
||||
github.com/luxfi/fhe v1.7.7 h1:RP26i3CxvNy2y/3LKiJPgd9uR5MrlG/MvQnv5rkQFhk=
|
||||
github.com/luxfi/fhe v1.7.7/go.mod h1:FHfGNgKL5ZLcnKVKFVNLDJOBbQyQm5DGpVrMnY8ASJo=
|
||||
github.com/luxfi/geth v1.16.79 h1:MtP8ZUuSVZDjmZDa1kTJCl0PpG8+wGbQft652GO6a3A=
|
||||
@@ -398,6 +402,8 @@ github.com/luxfi/sampler v1.0.0 h1:k8Sf6otW83w4pQp0jXLA+g3J/joB7w7SqXQsWmNTOV0=
|
||||
github.com/luxfi/sampler v1.0.0/go.mod h1:f96/ozlj9vFfZj+akLtrHn4VpulQahwB+MQQhpeIekk=
|
||||
github.com/luxfi/threshold v1.6.0 h1:pq/n1iYowws+CXe/+slJodjPlJ152hFF94luHp2E82c=
|
||||
github.com/luxfi/threshold v1.6.0/go.mod h1:XWSfWM3n/tVggluh/LH7is4vYL85zmyMHCqfz2qrYVU=
|
||||
github.com/luxfi/threshold v1.6.4 h1:SDExhsRJovCccvCQwWK5TUpa5u4upXGEnEDW/XGB7/k=
|
||||
github.com/luxfi/threshold v1.6.4/go.mod h1:jNBQbeBMmxz9xYSWIer2kOMqq49mYIszSZwTdk1odc0=
|
||||
github.com/luxfi/utils v1.1.4 h1:8OY0jXCkpp6OotN1Y++6DATJkvtEwzq2k0p56imJlAk=
|
||||
github.com/luxfi/utils v1.1.4/go.mod h1:c3yz1RjzrB+cs5GZm+q1T3/2cCKElO9vxm9yRRtgSEM=
|
||||
github.com/luxfi/zap v0.2.0 h1:RzvOkp3EoN5UCkpnqfObHLM1sEHy7YcxXKuermhE/VA=
|
||||
@@ -593,6 +599,8 @@ go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
|
||||
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
|
||||
go.uber.org/mock v0.6.0 h1:hyF9dfmbgIX5EfOdasqLsWD6xqpNZlXblLB/Dbnwv3Y=
|
||||
go.uber.org/mock v0.6.0/go.mod h1:KiVJ4BqZJaMj4svdfmHM0AUx4NJYO8ZNpPnZn1Z+BBU=
|
||||
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
|
||||
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
|
||||
go.yaml.in/yaml/v2 v2.4.4 h1:tuyd0P+2Ont/d6e2rl3be67goVK4R6deVxCUX5vyPaQ=
|
||||
go.yaml.in/yaml/v2 v2.4.4/go.mod h1:gMZqIpDtDqOfM0uNfy0SkpRhvUryYH0Z6wdMYcacYXQ=
|
||||
go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc=
|
||||
|
||||
@@ -16,6 +16,7 @@ import (
|
||||
"github.com/luxfi/mpc/pkg/custody"
|
||||
"github.com/luxfi/mpc/pkg/db"
|
||||
"github.com/luxfi/mpc/pkg/txtracker"
|
||||
"github.com/luxfi/mpc/pkg/wallet"
|
||||
"github.com/luxfi/mpc/pkg/webauthn"
|
||||
)
|
||||
|
||||
@@ -84,6 +85,14 @@ type Server struct {
|
||||
router chi.Router
|
||||
replayGuard *replayGuard
|
||||
|
||||
// approval is the executive-approval registry consumed by /v1/approval/*.
|
||||
// Optional — when nil, those endpoints return 503. Wired via SetApproval.
|
||||
approval *ApprovalRegistry
|
||||
|
||||
// tieredWallets is the tiered-wallet registry consumed by /v1/wallets/*.
|
||||
// Lazily initialized when nil; wired via SetTieredWalletRegistry.
|
||||
tieredWallets wallet.Registry
|
||||
|
||||
// Events is the broadcast channel for server-side events (intent status,
|
||||
// signing progress, wallet events). Handlers publish here; WebSocket
|
||||
// clients and ZAP subscribers receive.
|
||||
|
||||
+4
-80
@@ -4,7 +4,6 @@ import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/luxfi/fhe"
|
||||
"github.com/luxfi/threshold/pkg/party"
|
||||
|
||||
"github.com/luxfi/mpc/pkg/identity"
|
||||
@@ -554,85 +553,10 @@ func (p *Node) CreateReshareSession(
|
||||
}
|
||||
}
|
||||
|
||||
// CreateTFHEKeyGenSession creates a threshold FHE key generation session
|
||||
// TFHE enables computation on encrypted data using lattice-based cryptography
|
||||
func (p *Node) CreateTFHEKeyGenSession(
|
||||
walletID string,
|
||||
threshold int,
|
||||
resultQueue messaging.MessageQueue,
|
||||
orgID string,
|
||||
) (*tfheKeygenSession, error) {
|
||||
if !p.peerRegistry.ArePeersReady() {
|
||||
return nil, fmt.Errorf(
|
||||
"peers are not ready yet. ready: %d, expected: %d",
|
||||
p.peerRegistry.GetReadyPeersCount(),
|
||||
len(p.peerIDs)+1,
|
||||
)
|
||||
}
|
||||
|
||||
readyPeerIDs := p.peerRegistry.GetReadyPeersIncludeSelf()
|
||||
// TFHE uses version 0 for raw party IDs
|
||||
selfPartyID, allPartyIDs := p.generatePartyIDs(PurposeKeygen, readyPeerIDs, 0)
|
||||
|
||||
// Use default FHE parameters (128-bit security)
|
||||
params, err := fhe.NewParametersFromLiteral(fhe.PN10QP27)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create FHE parameters: %w", err)
|
||||
}
|
||||
|
||||
session := newTFHEKeygenSession(
|
||||
walletID,
|
||||
p.pubSub,
|
||||
selfPartyID,
|
||||
allPartyIDs,
|
||||
threshold,
|
||||
params,
|
||||
p.kvstore,
|
||||
p.keyinfoStore,
|
||||
resultQueue,
|
||||
p.identityStore,
|
||||
orgID,
|
||||
)
|
||||
|
||||
return session, nil
|
||||
}
|
||||
|
||||
// CreateTFHEComputeSession creates a session for threshold FHE computation
|
||||
// Requires a wallet that was created with CreateTFHEKeyGenSession
|
||||
func (p *Node) CreateTFHEComputeSession(
|
||||
sessionID string,
|
||||
walletID string,
|
||||
participantPeerIDs []string,
|
||||
resultQueue messaging.MessageQueue,
|
||||
orgID string,
|
||||
) (TFHESession, error) {
|
||||
// Check if this node is in the participant list
|
||||
if !contains(participantPeerIDs, p.nodeID) {
|
||||
return nil, ErrNotInParticipantList
|
||||
}
|
||||
|
||||
// Generate party IDs for participants
|
||||
selfPartyID, participantPartyIDs := p.generatePartyIDs(PurposeKeygen, participantPeerIDs, 0)
|
||||
|
||||
session, err := newTFHEComputeSession(
|
||||
sessionID,
|
||||
walletID,
|
||||
p.pubSub,
|
||||
selfPartyID,
|
||||
participantPartyIDs,
|
||||
p.kvstore,
|
||||
p.keyinfoStore,
|
||||
resultQueue,
|
||||
p.identityStore,
|
||||
orgID,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return session, nil
|
||||
}
|
||||
|
||||
// CreateTFHEKeyGenSession and CreateTFHEComputeSession are gated behind the
|
||||
// `experimental_tfhe` build tag. See pkg/mpc/tfhe_node.go (experimental impl)
|
||||
// and pkg/mpc/tfhe_node_stub.go (default-build stub returning
|
||||
// ErrTFHENotImplemented).
|
||||
|
||||
func contains(slice []string, item string) bool {
|
||||
for _, s := range slice {
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
// Copyright (c) 2026, Lux Industries Inc
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
package mpc
|
||||
|
||||
import "errors"
|
||||
|
||||
// ErrTFHENotImplemented is returned by every TFHE wallet keygen / compute
|
||||
// entry point in default builds.
|
||||
//
|
||||
// The threshold-FHE wallet ceremony in this codebase is wired to
|
||||
// luxfi/threshold/protocols/tfhe, which 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. The
|
||||
// upstream package panics at every entry point unless
|
||||
// LUX_ALLOW_FAKE_TFHE_FOR_TESTING_ONLY=1 is set, by design.
|
||||
//
|
||||
// Real-threshold wiring (luxfi/lattice Shamir/LWE) is tracked as a separate
|
||||
// multi-week task per lps/LP-137-TFHE-REAL-THRESHOLD-SPEC.md §2.6. Until that
|
||||
// lands, the wallet keygen / compute path is gated behind the
|
||||
// `experimental_tfhe` build tag and default production builds reject every
|
||||
// caller with this error.
|
||||
var ErrTFHENotImplemented = errors.New("mpc/tfhe: threshold-FHE wallet keygen requires real Shamir/LWE threshold (LP-137 §2.6); placeholder UNSAFE primitive is gated behind the `experimental_tfhe` build tag")
|
||||
@@ -0,0 +1,100 @@
|
||||
// Copyright (c) 2024-2026, Lux Industries Inc
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
//go:build experimental_tfhe
|
||||
|
||||
// Experimental TFHE wallet ceremony wiring on Node. Default builds use
|
||||
// tfhe_node_stub.go which returns ErrTFHENotImplemented.
|
||||
|
||||
package mpc
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/luxfi/fhe"
|
||||
|
||||
"github.com/luxfi/mpc/pkg/messaging"
|
||||
)
|
||||
|
||||
// CreateTFHEKeyGenSession creates a threshold FHE key generation session.
|
||||
// EXPERIMENTAL: backed by the placeholder UNSAFE primitive in
|
||||
// luxfi/threshold/protocols/tfhe (every party stores the full master key).
|
||||
// Compile with `-tags experimental_tfhe` to enable; production must wait for
|
||||
// real Shamir/LWE wiring per LP-137 §2.6.
|
||||
func (p *Node) CreateTFHEKeyGenSession(
|
||||
walletID string,
|
||||
threshold int,
|
||||
resultQueue messaging.MessageQueue,
|
||||
orgID string,
|
||||
) (Session, error) {
|
||||
if !p.peerRegistry.ArePeersReady() {
|
||||
return nil, fmt.Errorf(
|
||||
"peers are not ready yet. ready: %d, expected: %d",
|
||||
p.peerRegistry.GetReadyPeersCount(),
|
||||
len(p.peerIDs)+1,
|
||||
)
|
||||
}
|
||||
|
||||
readyPeerIDs := p.peerRegistry.GetReadyPeersIncludeSelf()
|
||||
// TFHE uses version 0 for raw party IDs
|
||||
selfPartyID, allPartyIDs := p.generatePartyIDs(PurposeKeygen, readyPeerIDs, 0)
|
||||
|
||||
// Use default FHE parameters (128-bit security)
|
||||
params, err := fhe.NewParametersFromLiteral(fhe.PN10QP27)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create FHE parameters: %w", err)
|
||||
}
|
||||
|
||||
session := newTFHEKeygenSession(
|
||||
walletID,
|
||||
p.pubSub,
|
||||
selfPartyID,
|
||||
allPartyIDs,
|
||||
threshold,
|
||||
params,
|
||||
p.kvstore,
|
||||
p.keyinfoStore,
|
||||
resultQueue,
|
||||
p.identityStore,
|
||||
orgID,
|
||||
)
|
||||
|
||||
return session, nil
|
||||
}
|
||||
|
||||
// CreateTFHEComputeSession creates a session for threshold FHE computation.
|
||||
// EXPERIMENTAL: backed by the placeholder UNSAFE primitive in
|
||||
// luxfi/threshold/protocols/tfhe.
|
||||
func (p *Node) CreateTFHEComputeSession(
|
||||
sessionID string,
|
||||
walletID string,
|
||||
participantPeerIDs []string,
|
||||
resultQueue messaging.MessageQueue,
|
||||
orgID string,
|
||||
) (Session, error) {
|
||||
// Check if this node is in the participant list
|
||||
if !contains(participantPeerIDs, p.nodeID) {
|
||||
return nil, ErrNotInParticipantList
|
||||
}
|
||||
|
||||
// Generate party IDs for participants
|
||||
selfPartyID, participantPartyIDs := p.generatePartyIDs(PurposeKeygen, participantPeerIDs, 0)
|
||||
|
||||
session, err := newTFHEComputeSession(
|
||||
sessionID,
|
||||
walletID,
|
||||
p.pubSub,
|
||||
selfPartyID,
|
||||
participantPartyIDs,
|
||||
p.kvstore,
|
||||
p.keyinfoStore,
|
||||
resultQueue,
|
||||
p.identityStore,
|
||||
orgID,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return session, nil
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
// Copyright (c) 2026, Lux Industries Inc
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
//go:build !experimental_tfhe
|
||||
|
||||
// Default-build stub for the threshold-FHE wallet ceremony. The real
|
||||
// implementation lives in tfhe_node.go behind the `experimental_tfhe` build
|
||||
// tag. Production builds reject every caller with ErrTFHENotImplemented
|
||||
// because the upstream luxfi/threshold/protocols/tfhe primitive is a
|
||||
// fail-loud placeholder (every party stores the full master key — see
|
||||
// lps/LP-137-TFHE-REAL-THRESHOLD-SPEC.md §2.6).
|
||||
|
||||
package mpc
|
||||
|
||||
import "github.com/luxfi/mpc/pkg/messaging"
|
||||
|
||||
// CreateTFHEKeyGenSession returns ErrTFHENotImplemented in default builds.
|
||||
// Compile with `-tags experimental_tfhe` to opt into the placeholder UNSAFE
|
||||
// primitive (which itself requires LUX_ALLOW_FAKE_TFHE_FOR_TESTING_ONLY=1 at
|
||||
// runtime to avoid panicking — by design).
|
||||
func (p *Node) CreateTFHEKeyGenSession(
|
||||
walletID string,
|
||||
threshold int,
|
||||
resultQueue messaging.MessageQueue,
|
||||
orgID string,
|
||||
) (Session, error) {
|
||||
_ = walletID
|
||||
_ = threshold
|
||||
_ = resultQueue
|
||||
_ = orgID
|
||||
return nil, ErrTFHENotImplemented
|
||||
}
|
||||
|
||||
// CreateTFHEComputeSession returns ErrTFHENotImplemented in default builds.
|
||||
// See CreateTFHEKeyGenSession for the rationale.
|
||||
func (p *Node) CreateTFHEComputeSession(
|
||||
sessionID string,
|
||||
walletID string,
|
||||
participantPeerIDs []string,
|
||||
resultQueue messaging.MessageQueue,
|
||||
orgID string,
|
||||
) (Session, error) {
|
||||
_ = sessionID
|
||||
_ = walletID
|
||||
_ = participantPeerIDs
|
||||
_ = resultQueue
|
||||
_ = orgID
|
||||
return nil, ErrTFHENotImplemented
|
||||
}
|
||||
+13
-1
@@ -1,6 +1,18 @@
|
||||
// Copyright (c) 2024-2025, Lux Industries Inc
|
||||
// Copyright (c) 2024-2026, Lux Industries Inc
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
//go:build experimental_tfhe
|
||||
|
||||
// Package-level note: this file is the EXPERIMENTAL threshold-FHE wallet
|
||||
// keygen / compute path. It is gated behind the `experimental_tfhe` build tag
|
||||
// because the underlying primitive in luxfi/threshold/protocols/tfhe is a
|
||||
// fail-loud placeholder that does NOT implement real Shamir/LWE threshold
|
||||
// decryption (every party stores the full master key — see
|
||||
// lps/LP-137-TFHE-REAL-THRESHOLD-SPEC.md §2.6). Default builds compile the
|
||||
// stubs in tfhe_node_stub.go which return ErrTFHENotImplemented from every
|
||||
// entry point. Real-threshold wiring (luxfi/lattice Shamir/LWE) is tracked
|
||||
// as a multi-week separate task per LP-137 §2.6.
|
||||
|
||||
package mpc
|
||||
|
||||
import (
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
// Copyright (c) 2026, Lux Industries Inc.
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
//
|
||||
// TestMain opts the policy-package tests that touch
|
||||
// luxfi/threshold/protocols/tfhe (RealThresholdDecryptor wires its
|
||||
// PartialDecrypter / ShareAggregator) into the placeholder UNSAFE primitive
|
||||
// by setting LUX_ALLOW_FAKE_TFHE_FOR_TESTING_ONLY=1 for the duration of the
|
||||
// test binary. Production paths in luxfi/threshold/protocols/tfhe are
|
||||
// guarded by guardUnsafe() and panic when this env var is unset (by design).
|
||||
//
|
||||
// These tests verify dispatcher fan-out and aggregator wiring shape only —
|
||||
// they do NOT verify any threshold security property because the
|
||||
// underlying scheme has none. Real-threshold wiring (luxfi/lattice
|
||||
// Shamir/LWE) is tracked as a separate multi-week task per
|
||||
// lps/LP-137-TFHE-REAL-THRESHOLD-SPEC.md §2.6.
|
||||
|
||||
package policy
|
||||
|
||||
import (
|
||||
"os"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
if err := os.Setenv("LUX_ALLOW_FAKE_TFHE_FOR_TESTING_ONLY", "1"); err != nil {
|
||||
panic("policy test setup: cannot set LUX_ALLOW_FAKE_TFHE_FOR_TESTING_ONLY: " + err.Error())
|
||||
}
|
||||
os.Exit(m.Run())
|
||||
}
|
||||
Reference in New Issue
Block a user