Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
146 commits
Select commit Hold shift + click to select a range
b06bbaa
Harden sensitive legacy surfaces
mswilkison May 4, 2026
8817b28
Add sensitive fix regression coverage
mswilkison May 5, 2026
a758f92
Allow PR path filters to read changed files
mswilkison May 5, 2026
69f80a0
fix: address review findings from sensitive security fixes
piotr-roslaniec May 5, 2026
10c175f
docs(security): align operator-facing samples with diagnostics opt-in…
lrsaturnino May 6, 2026
bccf04e
fix(deps): remediate Sysdig keep-client:v2.5.2 image vulnerabilities …
mswilkison May 23, 2026
e778e25
fix(docker): bump Alpine base 3.21 -> 3.23 for OS-package CVEs (#15)
piotr-roslaniec May 23, 2026
c608136
fix(deps): bump go-ethereum v1.13.15 -> v1.17.3 (#13)
mswilkison May 23, 2026
094209a
Add renovate.json (#7)
renovate[bot] May 23, 2026
b46073e
fix(bitcoin): bounds-check untrusted transaction indexing (OOB crash …
piotr-roslaniec Jun 11, 2026
7ebd54e
fix(beacon/gjkr): guard nil revealed share in ComputeGroupPublicKeySh…
piotr-roslaniec Jun 11, 2026
8d8273e
fix(chain/ethereum): map RedemptionRequested TxMaxFee from the correc…
piotr-roslaniec Jun 11, 2026
e24c1b3
fix(tbtc): eliminate data races in signingDoneCheck
piotr-roslaniec May 6, 2026
7f8a1e7
test(net/retransmission): fix racy assertion in TestRetransmitExpecte…
piotr-roslaniec Jun 11, 2026
59064ed
fix(net/retransmission): eliminate data races in Ticker shutdown and …
piotr-roslaniec Jun 11, 2026
d4704f6
chore: open testing-hardening epic integration branch
piotr-roslaniec Jun 11, 2026
91568b8
ci(client): add non-blocking race-detector test job
piotr-roslaniec Jun 11, 2026
93c9a50
ci(client): enforce bounds-checked Transaction indexing via golangci-…
piotr-roslaniec Jun 11, 2026
24c72f4
fix(client): bounds-check node-supplied tx indexing in redemption/mov…
piotr-roslaniec Jun 11, 2026
7396add
test(bitcoin): add native coverage-guided fuzz targets for untrusted …
piotr-roslaniec Jun 11, 2026
4758495
test: native fuzz targets for untrusted protobuf message unmarshalers
piotr-roslaniec Jun 11, 2026
04d9032
test(bitcoin): make fuzz seeds self-contained for the native-fuzzing …
piotr-roslaniec Jun 11, 2026
e7d063d
Revert "Merge pull request #33 from tlabs-xyz/epic/testing"
piotr-roslaniec Jun 12, 2026
9e7753c
fix(deps): update golang.org/x/exp digest to c48552f
renovate[bot] Jun 12, 2026
cb81c05
chore(deps): update github.com/threshold-network/tss-lib digest to 86…
renovate[bot] Jun 17, 2026
5494b49
chore(deps): go mod tidy after merging x/exp (#23) and tss-lib (#19) …
Jun 17, 2026
093e37c
fix(deps): replace dependency redux-devtools-extension with @redux-de…
renovate[bot] Jun 11, 2026
92493d1
chore(deps): replace dependency babel-eslint with @babel/eslint-parse…
renovate[bot] Jun 11, 2026
80b4b47
chore(deps): regenerate token-stakedrop lockfile for @babel/eslint-pa…
Jun 17, 2026
e7cadc4
chore: seed Tier 2 Byzantine DST epic
piotr-roslaniec Jun 12, 2026
6cc3402
test(dkgtest): add Tier-2 determinism probe (work-package 0)
piotr-roslaniec Jun 12, 2026
2a51ed8
feat(interception): sender-attributed Strategy action API
piotr-roslaniec Jun 12, 2026
1582052
test(byzantine): add Byzantine strategy library and DKG scenarios
piotr-roslaniec Jun 12, 2026
26cf4cd
test(signing): whole-protocol tECDSA signing harness + Byzantine scen…
piotr-roslaniec Jun 12, 2026
425a6ce
test(tbtc): Byzantine coordination harness + withholding-leader scenario
piotr-roslaniec Jun 12, 2026
ac04a51
test(byzantine): F-008 reconstruction-path corroboration + dkgtest lo…
piotr-roslaniec Jun 12, 2026
b306300
test(signing): make Byzantine withhold test falsifiable
piotr-roslaniec Jun 15, 2026
36c8031
fix(byzantine): address review findings on interceptor strategy API
piotr-roslaniec Jun 12, 2026
e6d71b1
Revert "Revert "Merge pull request #33 from tlabs-xyz/epic/testing""
piotr-roslaniec Jun 12, 2026
1d19be0
docs(changelog): add CHANGELOG entry for testing/correctness hardenin…
Jun 17, 2026
24b6a07
docs(changelog): add CHANGELOG entry for Byzantine interceptor Strate…
Jun 17, 2026
dc88b27
docs(changelog): add CHANGELOG entry for tECDSA signing test harness …
Jun 17, 2026
15afaad
docs(changelog): add CHANGELOG entry for Byzantine coordination harne…
Jun 17, 2026
c87f24e
docs(changelog): add CHANGELOG entry for F-008 corroboration test (#40)
Jun 17, 2026
1ec4b51
ci: continuous fuzzing via ClusterFuzzLite (Tier 1 / 1b)
piotr-roslaniec Jun 11, 2026
97a57a0
ci(fuzz): grant security-events write for SARIF upload
piotr-roslaniec Jun 12, 2026
b4c41f9
test: rapid model-based property tests for the logic-bug class (Tier …
piotr-roslaniec Jun 11, 2026
433189b
chore: gitignore rapid property-test failure artifacts
piotr-roslaniec Jun 12, 2026
a103d6a
ci(client): alert on nightly race-detector failures and widen race ti…
piotr-roslaniec Jun 12, 2026
94a19ad
fix(lint): type-constrain the tx-indexing ruleguard rule to bitcoin.T…
piotr-roslaniec Jun 12, 2026
57b6805
fix(fuzz): pin go-118-fuzz-build to a commit SHA in the CFLite build
piotr-roslaniec Jun 12, 2026
3e47335
ci(fuzz): drop SARIF upload and pin ClusterFuzzLite actions by SHA
piotr-roslaniec Jun 12, 2026
dd46ad1
ci(fuzz): trigger PR fuzzing on fuzz-build infrastructure changes
piotr-roslaniec Jun 12, 2026
63d534a
ci(fuzz): guard against fuzz-target drift from the CFLite build list
piotr-roslaniec Jun 12, 2026
c00f798
test(net/libp2p): fuzz identity.Unmarshal, the pre-verification sende…
piotr-roslaniec Jun 12, 2026
f628ab5
test(chain/ethereum): assert all redemption event fields in the F-014…
piotr-roslaniec Jun 12, 2026
d51b30f
test(tecdsa/retry): assert success/failure explicitly in retry proper…
piotr-roslaniec Jun 12, 2026
f523fea
test(bitcoin): assert serialization fixed point in the transaction fu…
piotr-roslaniec Jun 12, 2026
bf70f8e
fix(fuzz): digest-pin the CFLite base-builder-go image
piotr-roslaniec Jun 12, 2026
aeac4da
docs(fuzz): require a fine-grained, single-repo PAT for corpus storage
piotr-roslaniec Jun 12, 2026
a700795
fix(fuzz): keep checkout paths out of the drift guard's sed pattern
piotr-roslaniec Jun 12, 2026
2977142
Bind tss-lib sessions to TECDSA session IDs
mswilkison May 19, 2026
ebf1490
Address session nonce review feedback
mswilkison May 19, 2026
dce5815
Strengthen session nonce wiring tests
mswilkison May 19, 2026
4cf57b6
Bind signing nonces to attempt start blocks
mswilkison May 19, 2026
cddfd9a
Update tss-lib hardening integration
mswilkison May 20, 2026
e4bd910
Thread signing/DKG session ID through attempt params
piotr-roslaniec May 23, 2026
29901ae
fix(signingtest): pad harness session ID to clear tss-lib 16-byte floor
Jun 17, 2026
8990098
security: add whitebox pentesting materials
piotr-roslaniec May 7, 2026
f58f7ad
security: add findings and ignore env files
piotr-roslaniec May 7, 2026
f765b01
security: unify findings into single F-01 through F-17 numbering
piotr-roslaniec May 7, 2026
d79d689
security: add verification status to all 17 findings
piotr-roslaniec May 7, 2026
a3838a1
security: update finding verification status to valid/not-remediated
piotr-roslaniec May 7, 2026
fa81d04
security: update F-04 and F-05 findings status
piotr-roslaniec May 8, 2026
f193d96
security: downgrade F-06 to Low/Informational -- on-chain BLS verify …
piotr-roslaniec May 8, 2026
26b4412
security: downgrade F-07 to Low/Mitigated by Design -- intentional cr…
piotr-roslaniec May 8, 2026
30516fa
security: downgrade F-08 to Low/Informational -- intentional post-TIP…
piotr-roslaniec May 8, 2026
52b116b
security: mark F-09 remediated -- ReentrancyGuard added to submitRela…
piotr-roslaniec May 8, 2026
d85da37
security: close F-10 as Informational -- cipher is XSalsa20-Poly1305 …
piotr-roslaniec May 8, 2026
c434c7b
security: update F-11 with self-correction (positive cache, not negat…
piotr-roslaniec May 8, 2026
d8a89aa
security: update F-12 -- downgrade to Low/Informational, remove K8s c…
piotr-roslaniec May 8, 2026
b861890
security: update F-13 as fixed -- deduplicator TOCTOU race resolved
piotr-roslaniec May 8, 2026
ebb75e7
security: close F-14 as informational -- v1 contracts deprecated, imm…
piotr-roslaniec May 8, 2026
506c9db
security: update F-15 as remediated -- exponent verified correct, tes…
piotr-roslaniec May 8, 2026
2639c9f
security: close F-16 as informational -- aggregation functions have n…
piotr-roslaniec May 8, 2026
a5e0c31
security: close F-17 as accepted -- single RPC endpoint is an archite…
piotr-roslaniec May 8, 2026
c37f2e8
security: update F-02 status to partially remediated; fix README find…
piotr-roslaniec May 8, 2026
5570115
security: mark F-03 remediated -- HKDF-SHA256 with domain separation …
piotr-roslaniec May 8, 2026
5d50c92
security: close F-01 as invalid -- persistence layer encrypts key sha…
piotr-roslaniec May 8, 2026
e81b4e8
security: sync findings with latest remediations
piotr-roslaniec May 8, 2026
ab0ac5d
security: address PR review feedback on findings and architecture docs
piotr-roslaniec May 12, 2026
3dbcac9
fix(altbn128): replace unbounded try-and-increment hash-to-curve with…
piotr-roslaniec May 8, 2026
07b7988
security(F-03): replace SHA-256 with HKDF-SHA256 for ECDH key derivation
piotr-roslaniec May 8, 2026
eade0fb
docs: add breaking changes changelog for security remediations
piotr-roslaniec May 8, 2026
e51570c
fix(random-beacon): add ReentrancyGuard to submitRelayEntry (F-09)
piotr-roslaniec May 8, 2026
7f7780b
fix(tbtc): eliminate deduplicator TOCTOU by replacing Has+Add with at…
piotr-roslaniec May 8, 2026
6296045
test(altbn128): assert sqrtGfP2 exponent matches (p^2+15)/32
piotr-roslaniec May 8, 2026
1bd601d
chore: ignore local env files and strix_runs directory
piotr-roslaniec May 8, 2026
844b394
test(gjkr): replace inlined ECDH label logic with gjkrEcdhInfo call i…
piotr-roslaniec May 8, 2026
2ae99f7
docs(altbn128): correct G1HashToPoint comment -- bounded but not norm…
piotr-roslaniec May 8, 2026
5b52bd0
fix(tbtc): clarify deduplicator comment -- mutex-serialized not hardw…
piotr-roslaniec May 8, 2026
de162b4
docs: correct G1HashToPoint timing claim in breaking changes doc
piotr-roslaniec May 8, 2026
f77a048
test(ephemeral): use labeled info in test helper; add nil-vs-label re…
piotr-roslaniec May 8, 2026
594f17b
ci: trigger contract workflows on security/whitebox-pentesting-materi…
piotr-roslaniec May 8, 2026
2576fe1
fix(random-beacon): replace OZ ReentrancyGuard with inline custom-err…
piotr-roslaniec May 8, 2026
edb51da
fix(random-beacon): fix Prettier formatting and gas offset for nonRee…
piotr-roslaniec May 8, 2026
6c5b01d
fix(random-beacon): update gas offset fixture to match new nonReentra…
piotr-roslaniec May 8, 2026
d38f3f9
fix(gjkr): expose gjkrEcdhInfo via export_test.go for external test p…
piotr-roslaniec May 8, 2026
953d5fc
fix(security): pin MemberIndex uint8 invariant, fix F-02 wording, doc…
piotr-roslaniec May 23, 2026
939515c
chore: trigger CI on PR #5 head
piotr-roslaniec May 23, 2026
add4a98
security: update F-09 fix description and add findings summary table …
piotr-roslaniec May 12, 2026
c89b4d0
security: downgrade F-02 to Low -- public inputs only
piotr-roslaniec May 12, 2026
5d4bf43
security: resync overview docs against post-fix code
piotr-roslaniec May 23, 2026
ddcbd58
test(altbn128,tbtc): pin G1 wire format and add F-13 concurrent regre…
piotr-roslaniec May 23, 2026
957b97e
test(random-beacon): add F-09 reentrancy, storage-layout, and gas-off…
piotr-roslaniec May 23, 2026
c29ec38
test(altbn128): gofmt fix on TestG1HashToPointWireFormat
piotr-roslaniec May 23, 2026
267b710
test(random-beacon): satisfy contracts-lint on new test files
piotr-roslaniec May 23, 2026
0c3d4ba
test(random-beacon): satisfy prettier on StorageLayout cast and strin…
piotr-roslaniec May 23, 2026
6a0281b
test(random-beacon): break long layout-assign per prettier
piotr-roslaniec May 23, 2026
be2cfe5
test(random-beacon): drop misframed refund-vs-cost check, fix slot he…
piotr-roslaniec May 23, 2026
2a6cf86
chore: gitignore .claude/ and remove accidentally tracked session lock
piotr-roslaniec May 23, 2026
7f0e4d3
test(random-beacon): remove stray blank line in Relay.test.ts
piotr-roslaniec May 23, 2026
85b55d5
test(random-beacon): zero-pad slot index for getStorageAt (32-byte hex)
piotr-roslaniec May 23, 2026
f43e1db
test(random-beacon): bypass ethers hexValue zero-stripping for getSto…
piotr-roslaniec May 23, 2026
f5e73e5
docs: add post-merge release and analysis notes
piotr-roslaniec May 23, 2026
03e022c
docs: add PR risk and release analyses for keep-common, tss-lib, keep…
piotr-roslaniec May 23, 2026
2de1b91
docs(changelog): assemble canonical CHANGELOG for all functional PRs …
Jun 17, 2026
170753c
fix(spv): compute required proof headers from actual header difficulties
lionakhnazarov Jun 12, 2026
980a3c8
test: align OOB guard error assertions with OutputAt/InputAt messages
lionakhnazarov Jun 23, 2026
266e57f
fix(bitcoin): align out-of-range test assertion with OutputAt message
lrsaturnino Jul 3, 2026
1311a58
fix(bitcoin): guard Difficulty against a zero target
lrsaturnino Jul 3, 2026
f775e6c
fix(beacon): make DKG-started deduplication atomic
lrsaturnino Jul 3, 2026
3d1e0f3
fix(random-beacon): preserve change period when finalizing decrease-d…
lrsaturnino Jul 3, 2026
44e2f1a
chore(spv): drop unused difficultyEpochLength constant and clarify he…
lrsaturnino Jul 3, 2026
54fd8c6
docs: clarify hash-to-point breaking-change scope and coordinated-upg…
lrsaturnino Jul 3, 2026
25ba6b3
fix(spv): fail loud on permanent proof header cap skip
lionakhnazarov Jul 9, 2026
fcebe93
fix(gjkr): fail closed on missing reconstructed share in phase 12
lionakhnazarov Jul 9, 2026
f1c67d9
docs: add BC/OV operator table and OV-2 metric rename to changelog
lionakhnazarov Jul 9, 2026
b41d429
chore: stop tracking Yarn install-state cache
lionakhnazarov Jul 9, 2026
3a12612
docs: reconcile tss-lib pin with go.mod in CHANGELOG
lionakhnazarov Jul 9, 2026
0c1e522
docs: label non-security infra and CI scope in CHANGELOG
lionakhnazarov Jul 9, 2026
cbf31e0
fix(rebase): restore go.sum and signing session-ID test expectations …
lionakhnazarov Jul 12, 2026
d2a6059
fix(dkgtest): restore RunTestWithStrategy lost in upstream rebase
lionakhnazarov Jul 15, 2026
1b0e945
fix(bitcoin,spv): use OutputAt for bounds-checked UTXO indexing
lionakhnazarov Jul 15, 2026
ec5dbd1
test(electrum): harden integration suite against dead public endpoints
lionakhnazarov Jul 15, 2026
971f603
fix(deps): restore go-ethereum v1.17.3 and Go 1.25 after rebase
lionakhnazarov Jul 16, 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