docs: add docs/audit.md and fix broken README links (closes #5)#7
Open
abhicris wants to merge 6 commits intoluxfi:mainfrom
Open
docs: add docs/audit.md and fix broken README links (closes #5)#7abhicris wants to merge 6 commits intoluxfi:mainfrom
abhicris wants to merge 6 commits intoluxfi:mainfrom
Conversation
…dcrd ToAffine mutates)
First practical threshold signature scheme compatible with NIST FIPS 204 ML-DSA. Outputs byte-identical standard ML-DSA signatures, enabling drop-in replacement of classical threshold ECDSA/Schnorr wallets with a PQ scheme that keeps the standardized verification path. Paper: Celi, del Pino, Espitau, Niot, Prest — Efficient Threshold ML-DSA, USENIX Security Symposium 2026. Files: - papers/threshold-mldsa.tex — paper summary + integration notes (LaTeX) - protocols/mldsa/doc.go — package doc - protocols/mldsa/params.go — (T,N) × level parameter tables (44/65/87) from paper Tables 3, 10, 11 - protocols/mldsa/rss.go — replicated secret sharing with hardcoded optimal partitions for 2 ≤ T ≤ N ≤ 6 (Appendix B, Algorithm 6) - protocols/mldsa/hrej.go — imbalanced hyperball rejection (Fig. 4) — mathematical spec stub, ring ops pending CIRCL integration - protocols/mldsa/rss_test.go — 6 tests covering subsets, recovery completeness, balance bounds, parameter coverage Config range: 2 ≤ T ≤ N ≤ 6 (2-of-3, 3-of-5, etc.) Security: static dishonest-majority in ROM under MLWE + ML-DSA unforgeability. Rounds: 3 per attempt, K parallel instances for ≥ 1/2 success probability.
Bench harness for 3 / 5 / 10 / 100 node PQ signing patterns: - individual: each validator signs, no aggregation (baseline) - committee: k-of-n sample signs, the LP-045 cluster cert - hierarchical: n validators in M clusters (LP-045 two-layer) Uses deterministic light mnemonic derivation — 100 validators from a single 32-byte master seed, no interactive keygen, no mainnet keys. Results on MacBook M3 / 10 cores / arm64 at ML-DSA-44: n=100 individual: 8.87 ms sign / 3.57 ms verify / 242 kB n=100 committee (k=32): 3.57 ms sign / 4.14 ms verify / 77 kB n=100 hierarchical (4 clusters): 14.7 ms sign / 5.35 ms verify Committee sampling cuts signing cost 3× vs all-100 signing. ML-DSA-65 is ~3× slower. Even at Level III, 100 validators sign in <30 ms per block — fine for quasar finality at any realistic block time. .gitignore: scope mldsa-bench binary ignore to repo root only so the cmd/mldsa-bench/ source dir is tracked.
Adds -mode=fixed which samples a fixed k-size committee regardless of total validator count N. Proves the scale-invariance claim in LP-045 + the PQ-finality-without-BLS proof (~/work/lux/proofs). Measured on MacBook M3 (arm64, 10 cores) at ML-DSA-44, k=128: N=1,000 sign=7.9ms verify=3.2ms cert=310 kB N=10,000 sign=7.4ms verify=3.2ms cert=310 kB N=100,000 sign=7.8ms verify=3.4ms cert=310 kB N=100,000 (ML-DSA-65): sign=10.8ms verify=5.9ms cert=424 kB Same cost from 10^3 to 10^5 validators. Only the VRF-based sampling touches N, and that is O(log N) in a weighted-reservoir implementation.
The README linked to `docs/audit.md`, `docs/api.md`, and `docs/integration.md` — none of which exist. This confuses users evaluating the library for production use. - Add `docs/audit.md` that honestly states external-audit status is "not yet commissioned", lists upstream primitive audits that users can rely on, documents known limitations, and points at the responsible-disclosure contact. The audit-log table is left empty for future audits to be appended. - Replace the two other dangling links (`api.md`, `integration.md`) with links to docs that actually exist in the repo today (`FROST.md`, `Broadcast.md`, `LUX_INTEGRATION.md`). Closes luxfi#5.
abhicris
pushed a commit
to abhicris/threshold
that referenced
this pull request
Apr 18, 2026
…closes luxfi#5) Land docs/audit.md covering: 1. Threat model — static, malicious, rushing adversary; adaptive corruption / DoS / physical side channels out of scope; network and randomness assumptions. 2. Protocol-by-protocol notes for CMP, FROST, LSS, Doerner, and Ringtail: reference papers (with eprint links), tolerance bound the proof gives, assumptions the proof relies on, implementation caveats specific to this repo. 3. BFT tolerance bounds — quick reference table plus a note on why the bound is t-1-out-of-n for threshold signing and not t<n/3 as in BFT consensus. 4. Post-quantum assumptions — classical protocols do not survive a Shor-capable adversary; Ringtail relies on M-LWE / M-SIS; hybrid-mode guidance for long-lived custody. 5. Deployment considerations — share storage, rotation, HSM integration (cross-linked to docs/hsm-integration.md), audit logging, secure channels, broadcast primitive. 6. Honest audit status — no external audit yet; upstream primitive audits (secp256k1 via dcrd, Paillier via taurushq, Ed25519 via filippo, BLAKE3 via lukechampine) documented; responsible disclosure process; empty audit log for future entries. Protocol claims cross-checked against the actual code in protocols/cmp/, protocols/frost/, protocols/lss/, protocols/doerner/, and protocols/ringtail/. The existing docs/ files (Threshold.md, FROST.md, Broadcast.md) are linked where they fill in the details. This supersedes the lightweight audit.md in PR luxfi#7 with the deeper structure the issue reporter asked for.
This was referenced Apr 18, 2026
zeekay
pushed a commit
that referenced
this pull request
Apr 23, 2026
The `Lint` job has been failing on master with:
can't load config: the Go language version (go1.24) used to build
golangci-lint is lower than the targeted Go version (1.26.1)
Root cause: `.github/workflows/ci.yml` used
`golangci/golangci-lint-action@v6` with `version: latest`, which resolves
to `golangci-lint v1.64.8`. That binary is built with Go 1.24, while
`go.mod` targets `go 1.26.1`. golangci-lint refuses to load the config
when the build-time Go version is lower than the `run.go` target it
infers from `go.mod`.
Minimal fix:
- Add `run.go: "1.24"` to `.golangci.yml` so the version check sees a
target equal to the build version and proceeds.
- Pin `golangci-lint-action` to `version: v1.64.8` explicitly. The v1
config format we use today is not parsed by golangci-lint v2.x, so
future drift of `latest` onto v2 would silently break us again.
Non-goals: migrating `.golangci.yml` to the v2 schema. That is a
separate, larger PR once a golangci-lint release built with Go 1.26 is
available.
This unblocks stalled docs PRs: #6, #7, #8 (all UNSTABLE purely because
of this lint failure on master).
— [kcolbchain](https://kcolbchain.com) / [Abhishek Krishna](https://abhishekkrishna.com)
cda4729 to
64b875c
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #5.
The README links to
docs/audit.md,docs/api.md, anddocs/integration.md— none of which exist in the tree today. This is particularly confusing for the audit link, since it leaves an evaluator unable to tell whether the library has been audited.Changes
docs/audit.mdthat honestly states external-audit status is "not yet commissioned", lists upstream primitive audits users can rely on (dcrd secp256k1, taurushq multi-party-sig, filippo edwards25519), documents known limitations (network layer, HSM claim, identifiable-abort caveats), and points atsecurity@lux.networkfor responsible disclosure. The audit-log table is left empty for future audits to be appended.FROST.md,Broadcast.md,LUX_INTEGRATION.md).Why the honest framing
A cryptographic-library README that claims "Audited Features" but links to a missing audit doc sets up the wrong expectation with downstream integrators. Better to be explicit about what has and hasn't been reviewed.
Happy to iterate on the text if the maintainers have concrete audit results they'd like linked instead.