Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
192 commits
Select commit Hold shift + click to select a range
a9436d2
Harden sensitive legacy surfaces
mswilkison May 4, 2026
f5aafb3
Add sensitive fix regression coverage
mswilkison May 5, 2026
6e51a10
Allow PR path filters to read changed files
mswilkison May 5, 2026
1eb42aa
fix: address review findings from sensitive security fixes
piotr-roslaniec May 5, 2026
918009d
docs(security): align operator-facing samples with diagnostics opt-in…
lrsaturnino May 6, 2026
4ad8d9e
security: add whitebox pentesting materials
piotr-roslaniec May 7, 2026
064ab9a
security: add findings and ignore env files
piotr-roslaniec May 7, 2026
dcd6658
security: unify findings into single F-01 through F-17 numbering
piotr-roslaniec May 7, 2026
785eb7a
security: add verification status to all 17 findings
piotr-roslaniec May 7, 2026
c57523b
security: update finding verification status to valid/not-remediated
piotr-roslaniec May 7, 2026
478c7c7
security: update F-04 and F-05 findings status
piotr-roslaniec May 8, 2026
1e60d67
security: downgrade F-06 to Low/Informational -- on-chain BLS verify …
piotr-roslaniec May 8, 2026
fe0a9a7
security: downgrade F-07 to Low/Mitigated by Design -- intentional cr…
piotr-roslaniec May 8, 2026
a16517d
security: downgrade F-08 to Low/Informational -- intentional post-TIP…
piotr-roslaniec May 8, 2026
07d4e5f
security: mark F-09 remediated -- ReentrancyGuard added to submitRela…
piotr-roslaniec May 8, 2026
e59df57
security: close F-10 as Informational -- cipher is XSalsa20-Poly1305 …
piotr-roslaniec May 8, 2026
8d45bf0
security: update F-11 with self-correction (positive cache, not negat…
piotr-roslaniec May 8, 2026
d30169b
security: update F-12 -- downgrade to Low/Informational, remove K8s c…
piotr-roslaniec May 8, 2026
4b23508
security: update F-13 as fixed -- deduplicator TOCTOU race resolved
piotr-roslaniec May 8, 2026
6fad6a0
security: close F-14 as informational -- v1 contracts deprecated, imm…
piotr-roslaniec May 8, 2026
9894703
security: update F-15 as remediated -- exponent verified correct, tes…
piotr-roslaniec May 8, 2026
d444761
security: close F-16 as informational -- aggregation functions have n…
piotr-roslaniec May 8, 2026
14055c9
security: close F-17 as accepted -- single RPC endpoint is an archite…
piotr-roslaniec May 8, 2026
67c38f1
security: update F-02 status to partially remediated; fix README find…
piotr-roslaniec May 8, 2026
289e1d5
security: mark F-03 remediated -- HKDF-SHA256 with domain separation …
piotr-roslaniec May 8, 2026
f8ffd4a
security: close F-01 as invalid -- persistence layer encrypts key sha…
piotr-roslaniec May 8, 2026
e37c772
security: sync findings with latest remediations
piotr-roslaniec May 8, 2026
122b3c8
ci: grant pull-requests:read permission to paths-filter jobs
piotr-roslaniec May 8, 2026
98fa073
security: address PR review feedback on findings and architecture docs
piotr-roslaniec May 12, 2026
4d3888a
fix(altbn128): replace unbounded try-and-increment hash-to-curve with…
piotr-roslaniec May 8, 2026
f176e1b
security(F-03): replace SHA-256 with HKDF-SHA256 for ECDH key derivation
piotr-roslaniec May 8, 2026
499f258
docs: add breaking changes changelog for security remediations
piotr-roslaniec May 8, 2026
757a5c1
fix(random-beacon): add ReentrancyGuard to submitRelayEntry (F-09)
piotr-roslaniec May 8, 2026
2057d26
fix(tbtc): eliminate deduplicator TOCTOU by replacing Has+Add with at…
piotr-roslaniec May 8, 2026
77b5287
test(altbn128): assert sqrtGfP2 exponent matches (p^2+15)/32
piotr-roslaniec May 8, 2026
5ff7430
chore(deps): update random-beacon yarn.lock after hardhat install
piotr-roslaniec May 8, 2026
65afe88
chore: ignore local env files and strix_runs directory
piotr-roslaniec May 8, 2026
3f7ab76
test(gjkr): replace inlined ECDH label logic with gjkrEcdhInfo call i…
piotr-roslaniec May 8, 2026
1b9ca07
docs(altbn128): correct G1HashToPoint comment -- bounded but not norm…
piotr-roslaniec May 8, 2026
abcdcc4
fix(tbtc): clarify deduplicator comment -- mutex-serialized not hardw…
piotr-roslaniec May 8, 2026
b6dd317
docs: correct G1HashToPoint timing claim in breaking changes doc
piotr-roslaniec May 8, 2026
6e63107
test(ephemeral): use labeled info in test helper; add nil-vs-label re…
piotr-roslaniec May 8, 2026
36d5b01
ci: trigger contract workflows on security/whitebox-pentesting-materi…
piotr-roslaniec May 8, 2026
17273fc
fix(random-beacon): replace OZ ReentrancyGuard with inline custom-err…
piotr-roslaniec May 8, 2026
5e6654d
fix(random-beacon): fix Prettier formatting and gas offset for nonRee…
piotr-roslaniec May 8, 2026
d96c65b
fix(random-beacon): update gas offset fixture to match new nonReentra…
piotr-roslaniec May 8, 2026
642a45d
fix(gjkr): expose gjkrEcdhInfo via export_test.go for external test p…
piotr-roslaniec May 8, 2026
9527196
security: update F-09 fix description and add findings summary table …
piotr-roslaniec May 12, 2026
c8d7133
security: downgrade F-02 to Low -- public inputs only
piotr-roslaniec May 12, 2026
6bca7ba
Bind tss-lib sessions to TECDSA session IDs
mswilkison May 19, 2026
2bafb14
Address session nonce review feedback
mswilkison May 19, 2026
c579dc5
Strengthen session nonce wiring tests
mswilkison May 19, 2026
023069e
Bump tss-lib hardening pin
mswilkison May 19, 2026
a8ae8f3
Bind signing nonces to attempt start blocks
mswilkison May 19, 2026
2ea49bd
Bump tss-lib pin to latest hardening head
mswilkison May 19, 2026
683bba9
Bump tss-lib pin after CI bootstrap merge
mswilkison May 20, 2026
d654b24
Bump tss-lib pin for proof review fixes
mswilkison May 20, 2026
2a70f81
Bump tss-lib pin after CI stabilization
mswilkison May 20, 2026
2ba4bb2
Update tss-lib hardening integration
mswilkison May 20, 2026
d53a4af
fix(libp2p): bound Keep handshake with a connection deadline
mswilkison May 22, 2026
f664d21
ci: grant pull-requests: read to path-filter detect-changes jobs
mswilkison May 22, 2026
f604325
Merge pull request #1 from tlabs-xyz/codex/sensitive-security-fixes
piotr-roslaniec May 23, 2026
202ffbe
fix(security): pin MemberIndex uint8 invariant, fix F-02 wording, doc…
piotr-roslaniec May 23, 2026
c5cd565
test(libp2p): tighten handshake-deadline regression test and clarify doc
piotr-roslaniec May 23, 2026
218b3aa
chore: trigger CI on PR #5 head
piotr-roslaniec May 23, 2026
e29fa36
Merge branch 'security/whitebox-pentesting-materials' into fix/securi…
piotr-roslaniec May 23, 2026
6c40c42
Merge pull request #9 from tlabs-xyz/fix/libp2p-handshake-timeout
piotr-roslaniec May 23, 2026
c6e2629
Merge pull request #5 from tlabs-xyz/fix/security-findings
piotr-roslaniec May 23, 2026
bbfc708
security: resync overview docs against post-fix code
piotr-roslaniec May 23, 2026
bf1fe2a
Merge remote-tracking branch 'origin/main' into security/whitebox-pen…
piotr-roslaniec May 23, 2026
861317c
docs: add post-merge release and analysis notes
piotr-roslaniec May 23, 2026
28b1095
fix(deps): remediate Sysdig keep-client:v2.5.2 image vulnerabilities …
mswilkison May 23, 2026
e5b9d89
test(altbn128,tbtc): pin G1 wire format and add F-13 concurrent regre…
piotr-roslaniec May 23, 2026
00458eb
test(random-beacon): add F-09 reentrancy, storage-layout, and gas-off…
piotr-roslaniec May 23, 2026
cf57166
fix(docker): bump Alpine base 3.21 -> 3.23 for OS-package CVEs (#15)
piotr-roslaniec May 23, 2026
2882f13
test(altbn128): gofmt fix on TestG1HashToPointWireFormat
piotr-roslaniec May 23, 2026
4660454
test(random-beacon): satisfy contracts-lint on new test files
piotr-roslaniec May 23, 2026
018d579
test(random-beacon): satisfy prettier on StorageLayout cast and strin…
piotr-roslaniec May 23, 2026
5653db8
test(random-beacon): break long layout-assign per prettier
piotr-roslaniec May 23, 2026
6772e2d
fix(deps): bump go-ethereum v1.13.15 -> v1.17.3 (#13)
mswilkison May 23, 2026
c336a31
test(random-beacon): drop misframed refund-vs-cost check, fix slot he…
piotr-roslaniec May 23, 2026
2d88360
chore: gitignore .claude/ and remove accidentally tracked session lock
piotr-roslaniec May 23, 2026
d68aeed
test(random-beacon): remove stray blank line in Relay.test.ts
piotr-roslaniec May 23, 2026
84e846a
test(random-beacon): zero-pad slot index for getStorageAt (32-byte hex)
piotr-roslaniec May 23, 2026
6a69600
test(random-beacon): bypass ethers hexValue zero-stripping for getSto…
piotr-roslaniec May 23, 2026
28ae0ae
Add renovate.json (#7)
renovate[bot] May 23, 2026
2855ad3
Thread signing/DKG session ID through attempt params
piotr-roslaniec May 23, 2026
dd208b7
docs: add PR risk and release analyses for keep-common, tss-lib, keep…
piotr-roslaniec May 23, 2026
03556cf
fix(bitcoin): bounds-check untrusted transaction indexing (OOB crash …
piotr-roslaniec Jun 11, 2026
925012d
fix(beacon/gjkr): guard nil revealed share in ComputeGroupPublicKeySh…
piotr-roslaniec Jun 11, 2026
736c261
fix(chain/ethereum): map RedemptionRequested TxMaxFee from the correc…
piotr-roslaniec Jun 11, 2026
f8421fb
fix(tbtc): eliminate data races in signingDoneCheck
piotr-roslaniec May 6, 2026
07350ee
fix/test(net/retransmission): fix BackoffStrategy data race and add L…
piotr-roslaniec May 6, 2026
aa29c92
fix(tecdsa/retry): use the right operator in triplet eligibility count
piotr-roslaniec Jun 11, 2026
6c42784
test(net/retransmission): fix racy assertion in TestRetransmitExpecte…
piotr-roslaniec Jun 11, 2026
dc04095
test(net/retransmission): replace sleep-based synchronization with de…
piotr-roslaniec Jun 11, 2026
cd2567e
fix(net/retransmission): eliminate data races in Ticker shutdown and …
piotr-roslaniec Jun 11, 2026
8b98b97
Merge pull request #27 from tlabs-xyz/security/fix-oob-crashes-and-ha…
piotr-roslaniec Jun 11, 2026
14c0a49
Merge pull request #28 from tlabs-xyz/security/backmerge-upstream-fixes
piotr-roslaniec Jun 11, 2026
6b87dec
ci(client): add non-blocking race-detector test job
piotr-roslaniec Jun 11, 2026
b5a3952
chore(deps): replace dependency babel-eslint with @babel/eslint-parse…
renovate[bot] Jun 11, 2026
5cb09ee
fix(deps): replace dependency redux-devtools-extension with @redux-de…
renovate[bot] Jun 11, 2026
9e24907
chore(deps): update dependency @keep-network/hardhat-local-networks-c…
renovate[bot] Jun 11, 2026
67ebcbd
chore(deps): update dependency @keep-network/sortition-pools to v2.0.0
renovate[bot] Jun 11, 2026
3ec0fe3
chore(deps): update dependency @nomiclabs/hardhat-etherscan to v3.1.8
renovate[bot] Jun 11, 2026
070725f
ci(client): enforce bounds-checked Transaction indexing via golangci-…
piotr-roslaniec Jun 11, 2026
3392368
test(bitcoin): add native coverage-guided fuzz targets for untrusted …
piotr-roslaniec Jun 11, 2026
fe31b5e
test: native fuzz targets for untrusted protobuf message unmarshalers
piotr-roslaniec Jun 11, 2026
b306278
test(bitcoin): make fuzz seeds self-contained for the native-fuzzing …
piotr-roslaniec Jun 11, 2026
eac8fc7
ci: continuous fuzzing via ClusterFuzzLite (Tier 1 / 1b)
piotr-roslaniec Jun 11, 2026
8460df2
test: rapid model-based property tests for the logic-bug class (Tier …
piotr-roslaniec Jun 11, 2026
76d3bed
chore: open testing-hardening epic integration branch
piotr-roslaniec Jun 11, 2026
f0f10cc
fix(client): bounds-check node-supplied tx indexing in redemption/mov…
piotr-roslaniec Jun 11, 2026
ebf8f8c
ci(fuzz): grant security-events write for SARIF upload
piotr-roslaniec Jun 12, 2026
da8bb80
chore: gitignore rapid property-test failure artifacts
piotr-roslaniec Jun 12, 2026
e840068
fix(deps): update golang.org/x/exp digest to c48552f
renovate[bot] Jun 12, 2026
c4e17db
Merge pull request #30 from tlabs-xyz/test/fuzz-parsers
piotr-roslaniec Jun 12, 2026
845e916
Merge pull request #32 from tlabs-xyz/test/rapid-properties
piotr-roslaniec Jun 12, 2026
6d3edd0
chore: seed Tier 2 Byzantine DST epic
piotr-roslaniec Jun 12, 2026
1b92434
test(dkgtest): add Tier-2 determinism probe (work-package 0)
piotr-roslaniec Jun 12, 2026
d9f4282
feat(interception): sender-attributed Strategy action API
piotr-roslaniec Jun 12, 2026
62350d2
test(byzantine): add Byzantine strategy library and DKG scenarios
piotr-roslaniec Jun 12, 2026
1eaaabe
Merge pull request #29 from tlabs-xyz/ci/tier0-race-and-lint
piotr-roslaniec Jun 12, 2026
51fdd8f
Merge pull request #33 from tlabs-xyz/epic/testing
piotr-roslaniec Jun 12, 2026
31f6b90
Revert "Merge pull request #33 from tlabs-xyz/epic/testing"
piotr-roslaniec Jun 12, 2026
973f92d
Merge remote-tracking branch 'origin/ci/clusterfuzzlite' into ci/tier…
piotr-roslaniec Jun 12, 2026
853e099
Revert "Revert "Merge pull request #33 from tlabs-xyz/epic/testing""
piotr-roslaniec Jun 12, 2026
dca5048
ci(client): alert on nightly race-detector failures and widen race ti…
piotr-roslaniec Jun 12, 2026
9781aa2
fix(lint): type-constrain the tx-indexing ruleguard rule to bitcoin.T…
piotr-roslaniec Jun 12, 2026
a01a702
fix(fuzz): pin go-118-fuzz-build to a commit SHA in the CFLite build
piotr-roslaniec Jun 12, 2026
16cd5b7
ci(fuzz): drop SARIF upload and pin ClusterFuzzLite actions by SHA
piotr-roslaniec Jun 12, 2026
c8e340d
test(signing): whole-protocol tECDSA signing harness + Byzantine scen…
piotr-roslaniec Jun 12, 2026
b98163f
ci(fuzz): trigger PR fuzzing on fuzz-build infrastructure changes
piotr-roslaniec Jun 12, 2026
c9cf2f2
ci(fuzz): guard against fuzz-target drift from the CFLite build list
piotr-roslaniec Jun 12, 2026
b75cf92
test(net/libp2p): fuzz identity.Unmarshal, the pre-verification sende…
piotr-roslaniec Jun 12, 2026
5f4aff9
test(chain/ethereum): assert all redemption event fields in the F-014…
piotr-roslaniec Jun 12, 2026
ec2d657
test(tecdsa/retry): assert success/failure explicitly in retry proper…
piotr-roslaniec Jun 12, 2026
960ff91
test(bitcoin): assert serialization fixed point in the transaction fu…
piotr-roslaniec Jun 12, 2026
562cce7
fix(fuzz): digest-pin the CFLite base-builder-go image
piotr-roslaniec Jun 12, 2026
66c461d
docs(fuzz): require a fine-grained, single-repo PAT for corpus storage
piotr-roslaniec Jun 12, 2026
1a3e126
fix(fuzz): keep checkout paths out of the drift guard's sed pattern
piotr-roslaniec Jun 12, 2026
0cd9390
test(tbtc): Byzantine coordination harness + withholding-leader scenario
piotr-roslaniec Jun 12, 2026
e2897ef
fix(byzantine): address review findings on interceptor strategy API
piotr-roslaniec Jun 12, 2026
1309136
test(byzantine): F-008 reconstruction-path corroboration + dkgtest lo…
piotr-roslaniec Jun 12, 2026
c217b29
test(signing): make Byzantine withhold test falsifiable
piotr-roslaniec Jun 15, 2026
1000a8a
Merge remote-tracking branch 'origin/main' into renovate/babel-eslint…
piotr-roslaniec Jun 17, 2026
50b7dd3
chore(deps): regenerate token-stakedrop lockfile for @babel/eslint-pa…
Jun 17, 2026
b44a272
Merge remote-tracking branch 'origin/main' into renovate/nomiclabs-ha…
piotr-roslaniec Jun 17, 2026
399d518
Merge remote-tracking branch 'origin/main' into renovate/keep-network…
piotr-roslaniec Jun 17, 2026
fd90575
chore(deps): update github.com/threshold-network/tss-lib digest to 86…
renovate[bot] Jun 17, 2026
2bee928
docs(changelog): add CHANGELOG entry for testing/correctness hardenin…
Jun 17, 2026
1a66e81
Merge remote-tracking branch 'origin/reland/epic-testing' into ci/clu…
piotr-roslaniec Jun 17, 2026
9267c44
docs(changelog): add CHANGELOG entry for ClusterFuzzLite + rapid prop…
Jun 17, 2026
a3bf9d6
Merge remote-tracking branch 'origin/reland/epic-testing' into epic/b…
piotr-roslaniec Jun 17, 2026
a4e846b
Merge remote-tracking branch 'origin/epic/byzantine-dst' into feat/by…
piotr-roslaniec Jun 17, 2026
b29f541
docs(changelog): add CHANGELOG entry for Byzantine interceptor Strate…
Jun 17, 2026
0e90316
Merge remote-tracking branch 'origin/feat/byzantine-interceptor-api' …
piotr-roslaniec Jun 17, 2026
696979c
docs(changelog): add CHANGELOG entry for tECDSA signing test harness …
Jun 17, 2026
aeb007f
Merge remote-tracking branch 'origin/feat/byzantine-signing-harness' …
piotr-roslaniec Jun 17, 2026
14897ec
docs(changelog): add CHANGELOG entry for Byzantine coordination harne…
Jun 17, 2026
fb167a3
Merge remote-tracking branch 'origin/feat/byzantine-coordination-harn…
piotr-roslaniec Jun 17, 2026
bbed37e
docs(changelog): add CHANGELOG entry for F-008 corroboration test (#40)
Jun 17, 2026
ef53f8b
docs(changelog): add CHANGELOG entry for tECDSA session-ID binding + …
Jun 17, 2026
cbc8877
docs(changelog): add CHANGELOG entry for pentest findings + security …
Jun 17, 2026
6c845a1
docs(changelog): add CHANGELOG entry for post-merge release/analysis …
Jun 17, 2026
aca0e1f
Merge remote-tracking branch 'origin/renovate/golang.org-x-exp-digest…
piotr-roslaniec Jun 17, 2026
5f48909
Merge remote-tracking branch 'origin/renovate/github.com-threshold-ne…
piotr-roslaniec Jun 17, 2026
1fe2b43
chore(deps): go mod tidy after merging x/exp (#23) and tss-lib (#19) …
Jun 17, 2026
9df324d
Merge remote-tracking branch 'origin/renovate/keep-network-sortition-…
piotr-roslaniec Jun 17, 2026
abcc1a4
Merge remote-tracking branch 'origin/renovate/redux-devtools-extensio…
piotr-roslaniec Jun 17, 2026
b70bd2b
Merge remote-tracking branch 'origin/renovate/babel-eslint-replacemen…
piotr-roslaniec Jun 17, 2026
54a2304
Merge remote-tracking branch 'origin/renovate/keep-network-hardhat-lo…
piotr-roslaniec Jun 17, 2026
8d127b9
Merge remote-tracking branch 'origin/renovate/nomiclabs-hardhat-ether…
piotr-roslaniec Jun 17, 2026
ba9bc72
Merge remote-tracking branch 'origin/feat/byzantine-f008-corroboratio…
piotr-roslaniec Jun 17, 2026
6acf924
Merge remote-tracking branch 'origin/ci/clusterfuzzlite' into epic-co…
Jun 17, 2026
4ecac7f
Merge remote-tracking branch 'origin/codex/session-nonce-binding' int…
Jun 17, 2026
38e6799
fix(signingtest): pad harness session ID to clear tss-lib 16-byte floor
Jun 17, 2026
4fb846f
Merge remote-tracking branch 'origin/security/whitebox-pentesting-mat…
Jun 17, 2026
7c45b26
Merge remote-tracking branch 'origin/docs/release-notes' into epic-co…
Jun 17, 2026
b47f32f
docs(changelog): assemble canonical CHANGELOG for all functional PRs …
Jun 17, 2026
ac63328
revert(deps): exclude #26 (hardhat-etherscan 3.1.8) from epic
piotr-roslaniec Jun 17, 2026
57a104d
merge(security): integrate keep-core-security epic-consolidation
lionakhnazarov Jun 23, 2026
d07eb41
fix(spv): compute required proof headers from actual header difficulties
lionakhnazarov Jun 12, 2026
dd2c873
test: align OOB guard error assertions with OutputAt/InputAt messages
lionakhnazarov Jun 23, 2026
e08b5a8
fix(bitcoin): align out-of-range test assertion with OutputAt message
lrsaturnino Jul 3, 2026
6da2ca7
fix(bitcoin): guard Difficulty against a zero target
lrsaturnino Jul 3, 2026
d2e1fe1
fix(beacon): make DKG-started deduplication atomic
lrsaturnino Jul 3, 2026
8600f0e
fix(random-beacon): preserve change period when finalizing decrease-d…
lrsaturnino Jul 3, 2026
b985b15
chore(spv): drop unused difficultyEpochLength constant and clarify he…
lrsaturnino Jul 3, 2026
d1bac22
docs: clarify hash-to-point breaking-change scope and coordinated-upg…
lrsaturnino Jul 3, 2026
fde5857
Merge pull request #13 from threshold-network/fix/pr4109-review-follo…
lionakhnazarov Jul 3, 2026
0224fdb
fix(random-beacon): restore Yarn 4 lockfile for immutable CI install
lionakhnazarov Jul 3, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions .clusterfuzzlite/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# ClusterFuzzLite / OSS-Fuzz build image for keep-core's native Go fuzz targets.
# base-builder-go provides the Go toolchain plus the compile_native_go_fuzzer
# helper used by build.sh.
#
# Digest-pinned: the :latest tag floats and the image is rebuilt upstream
# continuously; an unpinned base silently changes the build environment (and
# is a supply-chain vector) on every CI run. Bump the digest deliberately —
# resolve the current one with:
# curl -s "https://gcr.io/v2/oss-fuzz-base/base-builder-go/manifests/latest" \
# -H "Authorization: Bearer $(curl -s 'https://gcr.io/v2/token?service=gcr.io&scope=repository:oss-fuzz-base/base-builder-go:pull' | jq -r .token)" \
# -H "Accept: application/vnd.docker.distribution.manifest.list.v2+json" -I | grep -i docker-content-digest
FROM gcr.io/oss-fuzz-base/base-builder-go@sha256:cf761fd9baac42fff453259755067a7ad8ad70dbbe7db5027211e9fabc5cac40

# The ClusterFuzzLite build_fuzzers action supplies the checked-out repo as the
# Docker build context; copy it in and build from there.
COPY . $SRC/keep-core
WORKDIR $SRC/keep-core
COPY .clusterfuzzlite/build.sh $SRC/
104 changes: 104 additions & 0 deletions .clusterfuzzlite/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
# Continuous fuzzing

This directory wires keep-core's native Go fuzz targets (the `Fuzz*` functions
under `pkg/**/fuzz_test.go`) into **ClusterFuzzLite** — OSS-Fuzz's self-hosted
variant that runs in this repo's own GitHub Actions and **works on private
repos**. That last property is why ClusterFuzzLite, not OSS-Fuzz, is the right
tool for this fork (OSS-Fuzz only fuzzes public projects).

## Files

| file | purpose |
|---|---|
| `Dockerfile` | build image (`base-builder-go`) |
| `build.sh` | compiles every `Fuzz*` target into a libFuzzer binary (path-qualified output names — several `Fuzz*` funcs share a name across packages) |
| `project.yaml` | `language: go` |
| `../.github/workflows/cflite_pr.yml` | per-PR fuzzing of changed code (fast, exits on first crash) |
| `../.github/workflows/cflite_batch.yml` | scheduled longer run over all targets |

## Adding / regenerating targets

`build.sh` must list one `compile_native_go_fuzzer` line per `Fuzz*` target.
CI enforces this (`check_targets.sh` runs on every PR and fails on drift).
Regenerate after adding targets:

```sh
for f in $(grep -rln "func Fuzz.*testing.F" pkg/ --include="*_test.go" | sort); do
d=$(dirname "$f"); p="github.com/keep-network/keep-core/$d"
pref=$(echo "$d" | sed 's#^pkg/##; s#/#_#g')
grep -oE "func (Fuzz[A-Za-z0-9_]+)\(" "$f" | sed -E 's/func (Fuzz[A-Za-z0-9_]+)\(/\1/' \
| while read fn; do echo "compile_native_go_fuzzer $p $fn ${pref}_${fn}"; done
done
```

## Enabling corpus persistence (batch mode)

Batch fuzzing benefits from carrying the corpus between runs — without it
every nightly run restarts from the in-tree seeds and the 1800s budget is a
smoke test, not coverage-accumulating fuzzing. To enable:

1. Create a private storage repo, e.g. `tlabs-xyz/keep-core-security-fuzz-corpus`.
2. Add a `PERSONAL_ACCESS_TOKEN` repo secret. It MUST be a **fine-grained
PAT scoped to the storage repo only**, with `Contents: Read and write`
as its only permission. Never use a classic PAT here: the token is
interpolated into a clone URL inside a job that executes
repo-controlled build code (`build.sh`, `Dockerfile`), so an
over-scoped token would hand that code access to everything it can
reach. Set an expiry and rotate it.
3. Uncomment the `storage-repo*` lines in `cflite_batch.yml` (and
`upload-build`). Keep persistence OUT of `cflite_pr.yml`: PR jobs run
proposed code and must not see the token at all.

Until then, each batch run starts from the in-tree seed corpus.

## Fork-lifecycle policy (why this exists)

This is a **private fork** of the public `github.com/keep-network/keep-core`.
Fuzzing finds bugs in code; whether a finding is fork-relevant depends on how
far the fork has diverged. Two facts drive the policy:

- **Fixes do not flow back automatically.** A bug fixed upstream stays open in
this fork until deliberately back-merged (this engagement already hit exactly
that: upstream's OOB fix was incomplete and had to be back-merged by hand).
- **Fork-divergent code gets no upstream coverage.** OSS-Fuzz on the upstream
cannot see code that only exists here.

Policy:

1. **Run ClusterFuzzLite here** (this directory) so the fork's own code —
including divergent paths — is fuzzed in its own CI.
2. **Track upstream `main`**: reconcile within a bounded window (e.g. N commits
or one release) so shared-parser fixes found upstream reach the fork.
3. **Contribute the fuzz targets upstream** (below) so the shared parsers get
continuous OSS-Fuzz coverage at Google's scale, and so this fork inherits
that coverage on the shared code after each reconcile.

## OSS-Fuzz for the public upstream

The same `Dockerfile` / `build.sh` / targets work for OSS-Fuzz once the
`Fuzz*` targets are merged into `github.com/keep-network/keep-core`. To enroll
the upstream, open a PR to `google/oss-fuzz` adding `projects/keep-core/` with:

- `project.yaml`:

```yaml
homepage: "https://github.com/keep-network/keep-core"
language: go
primary_contact: "<security contact email>"
main_repo: "https://github.com/keep-network/keep-core"
fuzzing_engines:
- libfuzzer
sanitizers:
- address
```

- a `Dockerfile` that `git clone`s the upstream repo (instead of `COPY .`):

```dockerfile
FROM gcr.io/oss-fuzz-base/base-builder-go
RUN git clone --depth 1 https://github.com/keep-network/keep-core $SRC/keep-core
WORKDIR $SRC/keep-core
COPY build.sh $SRC/
```

- the same `build.sh` from this directory.
64 changes: 64 additions & 0 deletions .clusterfuzzlite/build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
#!/bin/bash -eu
#
# ClusterFuzzLite / OSS-Fuzz build script for keep-core native (testing.F)
# fuzz targets. Compiles every Fuzz* target into a libFuzzer binary. Output
# names are path-qualified because several Fuzz funcs share a name across
# packages (e.g. FuzzEphemeralPublicKeyMessageUnmarshal in gjkr/dkg/signing).
#
# Regenerate the target list with:
# grep -rhoE "func (Fuzz[A-Za-z0-9_]+)\(f \*testing.F\)" pkg/ --include="*_test.go"

cd "$SRC/keep-core"

# Fuzzers don't need VCS build stamping, and stamping can fail in the build
# container (git "dubious ownership" / detached checkout). Disable it.
export GOFLAGS="-buildvcs=false ${GOFLAGS:-}"

# compile_native_go_fuzzer rewrites each testing.F target onto the OSS-Fuzz
# libFuzzer shim; pull it into the module graph (build-container only, not
# committed to go.mod). Pinned to a commit SHA: this fetch happens outside
# go.sum protection on every CI build, so an unpinned HEAD would execute
# whatever upstream pushes. Bump deliberately.
go get github.com/AdamKorcz/go-118-fuzz-build/testing@a70c2aa677fa43583571959478decabe02a96cd6

compile_native_go_fuzzer github.com/keep-network/keep-core/pkg/beacon/dkg/result FuzzDKGResultHashSignatureMessageUnmarshal beacon_dkg_result_FuzzDKGResultHashSignatureMessageUnmarshal
compile_native_go_fuzzer github.com/keep-network/keep-core/pkg/beacon/entry FuzzSignatureShareMessageUnmarshal beacon_entry_FuzzSignatureShareMessageUnmarshal
compile_native_go_fuzzer github.com/keep-network/keep-core/pkg/beacon/gjkr FuzzEphemeralPublicKeyMessageUnmarshal beacon_gjkr_FuzzEphemeralPublicKeyMessageUnmarshal
compile_native_go_fuzzer github.com/keep-network/keep-core/pkg/beacon/gjkr FuzzMemberCommitmentsMessageUnmarshal beacon_gjkr_FuzzMemberCommitmentsMessageUnmarshal
compile_native_go_fuzzer github.com/keep-network/keep-core/pkg/beacon/gjkr FuzzPeerSharesMessageUnmarshal beacon_gjkr_FuzzPeerSharesMessageUnmarshal
compile_native_go_fuzzer github.com/keep-network/keep-core/pkg/beacon/gjkr FuzzSecretSharesAccusationsMessageUnmarshal beacon_gjkr_FuzzSecretSharesAccusationsMessageUnmarshal
compile_native_go_fuzzer github.com/keep-network/keep-core/pkg/beacon/gjkr FuzzMemberPublicKeySharePointsMessageUnmarshal beacon_gjkr_FuzzMemberPublicKeySharePointsMessageUnmarshal
compile_native_go_fuzzer github.com/keep-network/keep-core/pkg/beacon/gjkr FuzzPointsAccusationsMessageUnmarshal beacon_gjkr_FuzzPointsAccusationsMessageUnmarshal
compile_native_go_fuzzer github.com/keep-network/keep-core/pkg/beacon/gjkr FuzzMisbehavedEphemeralKeysMessageUnmarshal beacon_gjkr_FuzzMisbehavedEphemeralKeysMessageUnmarshal
compile_native_go_fuzzer github.com/keep-network/keep-core/pkg/bitcoin FuzzNewScriptFromVarLenData bitcoin_FuzzNewScriptFromVarLenData
compile_native_go_fuzzer github.com/keep-network/keep-core/pkg/bitcoin FuzzTransactionDeserialize bitcoin_FuzzTransactionDeserialize
compile_native_go_fuzzer github.com/keep-network/keep-core/pkg/net/libp2p FuzzIdentityUnmarshal net_libp2p_FuzzIdentityUnmarshal
compile_native_go_fuzzer github.com/keep-network/keep-core/pkg/net/security/handshake FuzzAct1MessageUnmarshal net_security_handshake_FuzzAct1MessageUnmarshal
compile_native_go_fuzzer github.com/keep-network/keep-core/pkg/net/security/handshake FuzzAct2MessageUnmarshal net_security_handshake_FuzzAct2MessageUnmarshal
compile_native_go_fuzzer github.com/keep-network/keep-core/pkg/net/security/handshake FuzzAct3MessageUnmarshal net_security_handshake_FuzzAct3MessageUnmarshal
compile_native_go_fuzzer github.com/keep-network/keep-core/pkg/protocol/announcer FuzzAnnouncementMessageUnmarshal protocol_announcer_FuzzAnnouncementMessageUnmarshal
compile_native_go_fuzzer github.com/keep-network/keep-core/pkg/protocol/inactivity FuzzClaimSignatureMessageUnmarshal protocol_inactivity_FuzzClaimSignatureMessageUnmarshal
compile_native_go_fuzzer github.com/keep-network/keep-core/pkg/tbtc FuzzSigningDoneMessageUnmarshal tbtc_FuzzSigningDoneMessageUnmarshal
compile_native_go_fuzzer github.com/keep-network/keep-core/pkg/tbtc FuzzCoordinationMessageUnmarshal tbtc_FuzzCoordinationMessageUnmarshal
compile_native_go_fuzzer github.com/keep-network/keep-core/pkg/tbtc FuzzNoopProposalUnmarshal tbtc_FuzzNoopProposalUnmarshal
compile_native_go_fuzzer github.com/keep-network/keep-core/pkg/tbtc FuzzHeartbeatProposalUnmarshal tbtc_FuzzHeartbeatProposalUnmarshal
compile_native_go_fuzzer github.com/keep-network/keep-core/pkg/tbtc FuzzDepositSweepProposalUnmarshal tbtc_FuzzDepositSweepProposalUnmarshal
compile_native_go_fuzzer github.com/keep-network/keep-core/pkg/tbtc FuzzRedemptionProposalUnmarshal tbtc_FuzzRedemptionProposalUnmarshal
compile_native_go_fuzzer github.com/keep-network/keep-core/pkg/tbtc FuzzMovingFundsProposalUnmarshal tbtc_FuzzMovingFundsProposalUnmarshal
compile_native_go_fuzzer github.com/keep-network/keep-core/pkg/tbtc FuzzMovedFundsSweepProposalUnmarshal tbtc_FuzzMovedFundsSweepProposalUnmarshal
compile_native_go_fuzzer github.com/keep-network/keep-core/pkg/tecdsa/dkg FuzzEphemeralPublicKeyMessageUnmarshal tecdsa_dkg_FuzzEphemeralPublicKeyMessageUnmarshal
compile_native_go_fuzzer github.com/keep-network/keep-core/pkg/tecdsa/dkg FuzzTssRoundOneMessageUnmarshal tecdsa_dkg_FuzzTssRoundOneMessageUnmarshal
compile_native_go_fuzzer github.com/keep-network/keep-core/pkg/tecdsa/dkg FuzzTssRoundTwoMessageUnmarshal tecdsa_dkg_FuzzTssRoundTwoMessageUnmarshal
compile_native_go_fuzzer github.com/keep-network/keep-core/pkg/tecdsa/dkg FuzzTssRoundThreeMessageUnmarshal tecdsa_dkg_FuzzTssRoundThreeMessageUnmarshal
compile_native_go_fuzzer github.com/keep-network/keep-core/pkg/tecdsa/dkg FuzzTssFinalizationMessageUnmarshal tecdsa_dkg_FuzzTssFinalizationMessageUnmarshal
compile_native_go_fuzzer github.com/keep-network/keep-core/pkg/tecdsa/dkg FuzzResultSignatureMessageUnmarshal tecdsa_dkg_FuzzResultSignatureMessageUnmarshal
compile_native_go_fuzzer github.com/keep-network/keep-core/pkg/tecdsa/signing FuzzEphemeralPublicKeyMessageUnmarshal tecdsa_signing_FuzzEphemeralPublicKeyMessageUnmarshal
compile_native_go_fuzzer github.com/keep-network/keep-core/pkg/tecdsa/signing FuzzTssRoundOneMessageUnmarshal tecdsa_signing_FuzzTssRoundOneMessageUnmarshal
compile_native_go_fuzzer github.com/keep-network/keep-core/pkg/tecdsa/signing FuzzTssRoundTwoMessageUnmarshal tecdsa_signing_FuzzTssRoundTwoMessageUnmarshal
compile_native_go_fuzzer github.com/keep-network/keep-core/pkg/tecdsa/signing FuzzTssRoundThreeMessageUnmarshal tecdsa_signing_FuzzTssRoundThreeMessageUnmarshal
compile_native_go_fuzzer github.com/keep-network/keep-core/pkg/tecdsa/signing FuzzTssRoundFourMessageUnmarshal tecdsa_signing_FuzzTssRoundFourMessageUnmarshal
compile_native_go_fuzzer github.com/keep-network/keep-core/pkg/tecdsa/signing FuzzTssRoundFiveMessageUnmarshal tecdsa_signing_FuzzTssRoundFiveMessageUnmarshal
compile_native_go_fuzzer github.com/keep-network/keep-core/pkg/tecdsa/signing FuzzTssRoundSixMessageUnmarshal tecdsa_signing_FuzzTssRoundSixMessageUnmarshal
compile_native_go_fuzzer github.com/keep-network/keep-core/pkg/tecdsa/signing FuzzTssRoundSevenMessageUnmarshal tecdsa_signing_FuzzTssRoundSevenMessageUnmarshal
compile_native_go_fuzzer github.com/keep-network/keep-core/pkg/tecdsa/signing FuzzTssRoundEightMessageUnmarshal tecdsa_signing_FuzzTssRoundEightMessageUnmarshal
compile_native_go_fuzzer github.com/keep-network/keep-core/pkg/tecdsa/signing FuzzTssRoundNineMessageUnmarshal tecdsa_signing_FuzzTssRoundNineMessageUnmarshal
40 changes: 40 additions & 0 deletions .clusterfuzzlite/check_targets.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#!/bin/bash -eu
#
# Drift guard: fails when the set of native Fuzz* targets under pkg/
# diverges from the compile_native_go_fuzzer registration list in
# build.sh. Without this, a new Fuzz* function compiles fine under
# `go test` but silently receives zero ClusterFuzzLite coverage.
#
# Compares exact (package, function) pairs — not counts — because
# several Fuzz functions share a name across packages.

repo_root="$(cd "$(dirname "$0")/.." && pwd)"
module="github.com/keep-network/keep-core"

# Work from the repo root so grep emits relative paths: the absolute path
# never enters the sed pattern, where regex metacharacters in a checkout
# location could otherwise misparse the target list.
cd "$repo_root"

expected="$(
grep -rn --include='*_test.go' -E '^func Fuzz[A-Za-z0-9_]+\(f \*testing\.F\)' pkg |
sed -E "s|^(.+)/[^/]+\.go:[0-9]+:func (Fuzz[A-Za-z0-9_]+)\(.*$|$module/\1 \2|" |
sort -u
)"

registered="$(
grep -E '^compile_native_go_fuzzer ' .clusterfuzzlite/build.sh |
awk '{print $2, $3}' |
sort -u
)"

if ! diff <(echo "$expected") <(echo "$registered") >&2; then
echo >&2
echo "Fuzz target drift detected:" >&2
echo " < targets found in pkg/ but not registered in .clusterfuzzlite/build.sh" >&2
echo " > targets registered in build.sh but missing from pkg/" >&2
echo "Add/remove the matching compile_native_go_fuzzer line(s)." >&2
exit 1
fi

echo "OK: $(echo "$expected" | wc -l) fuzz targets, build.sh registration list in sync."
11 changes: 11 additions & 0 deletions .clusterfuzzlite/project.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# ClusterFuzzLite project configuration. For CFLite only `language` is required;
# it is consumed by the build_fuzzers / run_fuzzers GitHub Actions.
#
# (The OSS-Fuzz integration for the PUBLIC upstream repo lives in the
# google/oss-fuzz repo under projects/keep-core/ and carries additional fields
# — homepage, primary_contact, main_repo, auto_ccs. See README.md.)
language: go
fuzzing_engines:
- libfuzzer
sanitizers:
- address
6 changes: 6 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# Hidden files and directories.
.*
# ...except the ClusterFuzzLite build files, which must reach the build context.
!.clusterfuzzlite
!.clusterfuzzlite/**

# Top-level directories unrelated to the build.
docs*/
Expand Down Expand Up @@ -29,6 +32,9 @@ token-tracker/
# Go stuff.
**/gen/_contracts
**/gen/**/*.go
# ...but keep the committed protobuf message code (gen/pb); the ClusterFuzzLite
# build does not run protoc, and the unmarshaler fuzz targets need it.
!**/gen/pb/*.go
!**/gen/gen.go
!**/gen/cmd/cmd.go

Expand Down
46 changes: 46 additions & 0 deletions .github/workflows/cflite_batch.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
name: ClusterFuzzLite batch fuzzing

# Scheduled longer fuzzing run over all targets to grow the corpus and reach
# deeper bugs than per-PR fuzzing can. Does not exit on first crash.
#
# Corpus/crash persistence requires a storage repo + a PERSONAL_ACCESS_TOKEN
# secret; uncomment the storage-repo lines once those exist (see
# .clusterfuzzlite/README.md). Without persistence the run still fuzzes but
# starts from the in-tree seed corpus each time.
on:
schedule:
- cron: "0 2 * * *" # daily, offset from the -race job (midnight)
workflow_dispatch:

# No security-events permission: this repo has no GitHub Advanced
# Security, so SARIF upload to code scanning would 403. Crash artifacts
# are reported via the action's run output and artifacts instead.
permissions:
contents: read

jobs:
Batch:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
sanitizer: [address]
steps:
- name: Build fuzzers (${{ matrix.sanitizer }})
id: build
uses: google/clusterfuzzlite/actions/build_fuzzers@82652fb49e77bc29c35da1167bb286e93c6bcc05 # v1
with:
language: go
sanitizer: ${{ matrix.sanitizer }}
# upload-build: true
- name: Run fuzzers (${{ matrix.sanitizer }})
id: run
uses: google/clusterfuzzlite/actions/run_fuzzers@82652fb49e77bc29c35da1167bb286e93c6bcc05 # v1
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
fuzz-seconds: 1800
mode: "batch"
sanitizer: ${{ matrix.sanitizer }}
# storage-repo: https://${{ secrets.PERSONAL_ACCESS_TOKEN }}@github.com/tlabs-xyz/keep-core-security-fuzz-corpus.git
# storage-repo-branch: main
# storage-repo-branch-coverage: gh-pages
62 changes: 62 additions & 0 deletions .github/workflows/cflite_pr.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
name: ClusterFuzzLite PR fuzzing

# Builds the native Go fuzz targets and fuzzes only the code changed in a PR
# (code-change mode), giving fast per-PR feedback. Exits on the first crash.
# Complements the nightly -race job and the batch fuzzer below.
on:
pull_request:
paths:
- "pkg/**"
- ".clusterfuzzlite/**"
# Infra the fuzz build depends on: a change here can break the
# CFLite build without touching pkg/, and would otherwise only be
# caught by the nightly batch run.
- "go.mod"
- "go.sum"
- ".dockerignore"
- ".github/workflows/cflite_pr.yml"
- ".github/workflows/cflite_batch.yml"

# No security-events permission: this repo has no GitHub Advanced
# Security, so SARIF upload to code scanning would 403. Crash artifacts
# are reported via the action's run output and artifacts instead.
permissions:
contents: read

jobs:
target-sync:
# build.sh's registration list is a second source of truth: a new
# Fuzz* function that is not registered silently gets zero CFLite
# coverage. Fail the PR instead.
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Check fuzz targets are registered in build.sh
run: ./.clusterfuzzlite/check_targets.sh

PR:
runs-on: ubuntu-latest
concurrency:
group: ${{ github.workflow }}-${{ matrix.sanitizer }}-${{ github.ref }}
cancel-in-progress: true
strategy:
fail-fast: false
matrix:
# Go native fuzzing builds under libFuzzer + AddressSanitizer.
sanitizer: [address]
steps:
- name: Build fuzzers (${{ matrix.sanitizer }})
id: build
uses: google/clusterfuzzlite/actions/build_fuzzers@82652fb49e77bc29c35da1167bb286e93c6bcc05 # v1
with:
language: go
github-token: ${{ secrets.GITHUB_TOKEN }}
sanitizer: ${{ matrix.sanitizer }}
- name: Run fuzzers (${{ matrix.sanitizer }})
id: run
uses: google/clusterfuzzlite/actions/run_fuzzers@82652fb49e77bc29c35da1167bb286e93c6bcc05 # v1
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
fuzz-seconds: 300
mode: "code-change"
sanitizer: ${{ matrix.sanitizer }}
Loading
Loading