Files
zeekay 93c5705815 feat(mpc): malicious layer — committed re-shares, identifiable opens, batched bit-validity
Closer (a) committed.go: cSHAKE256-committed BGW re-shares + exact degree
check (CheckDegree). Hash commitment is full-range-safe; the vss lattice
Pedersen binds only SHORT openings (MSIS) and is unsound for full-range GF(q)
re-shares — documented load-bearing departure from the HANDOFF seam.

Closer (c) openshare.go: commit-then-open binding names equivocators directly.
Identification rests on commitment binding, NOT RS error-correction (unsound at
N=2T-1 against T-1 corruptions — a T-1 coalition out-votes the honest T).

Closer (b) bitcheck.go: batched b·(b-1)=0 proof, Fiat-Shamir challenge bound to
the bit commitments, opened once (non-bit survives w.p. 1/q), per-party drill-down.

blame_bridge.go: mpc->blame bridge (scalar analogue of vss/blame.go); blame/ gains
ReasonBadReshare/BadOpening/BadBit + evidence shapes. Each re-check binds the
accused via its own signature, re-runs the scalar math — third-party verifiable.

go build/test/-race/vet green.
2026-06-27 21:00:16 -07:00

32 lines
1.3 KiB
Go

// Copyright (C) 2025-2026, Lux Industries Inc. All rights reserved.
// See the file LICENSE for licensing terms.
package mpc
import "golang.org/x/crypto/sha3"
// stream.go — a domain-separated cSHAKE256 byte stream. Used to (1) expand a
// Fiat-Shamir transcript hash into field elements (the bit-check challenge), and
// (2) give each independent CSCP coefficient its own reproducible, race-free
// randomness source derived from one master seed. It is an io.Reader so the
// field samplers (Field.Rand, RandBit) drive it directly.
// CShakeReader is an unbounded cSHAKE256 output stream keyed by a function name,
// a customization domain, and a seed. Reproducible: the same (funcName,
// customization, seed) yields the same bytes, so a committee run is KAT-stable
// and parallel workers never share state.
type CShakeReader struct {
h sha3.ShakeHash
}
// NewCShakeReader builds a cSHAKE256 stream over (funcName, customization, seed).
func NewCShakeReader(funcName, customization string, seed []byte) *CShakeReader {
h := sha3.NewCShake256([]byte(funcName), []byte(customization))
_, _ = h.Write(seed)
return &CShakeReader{h: h}
}
// Read fills p with stream bytes; it never returns an error (cSHAKE is
// unbounded).
func (r *CShakeReader) Read(p []byte) (int, error) { return r.h.Read(p) }