Skip to content

Comments

test: add BLS operations and IES encryption fuzz targets#7167

Open
thepastaclaw wants to merge 5 commits intodashpay:developfrom
thepastaclaw:fuzz/bls-operations
Open

test: add BLS operations and IES encryption fuzz targets#7167
thepastaclaw wants to merge 5 commits intodashpay:developfrom
thepastaclaw:fuzz/bls-operations

Conversation

@thepastaclaw
Copy link

@thepastaclaw thepastaclaw commented Feb 22, 2026

Summary

Add two new fuzz targets for Dash-specific BLS cryptographic operations (Phase 3 of the Dash Core Fuzzing Initiative).

bls_operations target

Fuzzes the core BLS operations that underpin Dash's LLMQ threshold signing, ChainLocks, and InstantSend:

  • Key generationCBLSSecretKey from fuzzed bytes + GetPublicKey() derivation
  • Signing & verificationSign() + VerifyInsecure() with both legacy and basic schemes
  • Fuzzed verification — completely random key/sig/hash combinations
  • Key aggregationAggregateInsecure() for public keys, signatures, and secret keys
  • Threshold operationsSecretKeyShare(), PublicKeyShare(), signature Recover()
  • DH key exchangeDHKeyExchange() with fuzzed inputs
  • Aggregated verificationVerifyInsecureAggregated() and VerifySecureAggregated()

Tests both legacy (LegacySchemeMPL) and basic (BasicSchemeMPL) BLS schemes via bls::bls_legacy_scheme.

bls_ies target

Fuzzes the BLS Integrated Encryption Scheme used for encrypted DKG contributions:

  • CBLSIESEncryptedBlob — decrypt with fuzzed keys and ciphertext
  • CBLSIESMultiRecipientBlobs — decrypt multiple fuzzed blobs
  • Encrypt/decrypt roundtrip — encrypt with valid keys, decrypt, assert plaintext equality

Safety

Both targets carefully filter fuzzed inputs to avoid triggering assertions or UB from accessing invalid BLS object internals — specifically:

  • AggregateInsecure(Span<..>) accesses .impl without validity checks → filter to valid keys/sigs
  • VerifySecureAggregated() accesses pk.impl directly → filter to valid public keys
  • VerifyInsecureAggregated() has assert(!pubKeys.empty()) → ensure non-empty after filtering
  • SecretKeyShare(), PublicKeyShare(), Recover() validate internally → safe with any input

Validation

Environment: Guix VM (Ubuntu 24.04, aarch64, clang 18)
Build: ./configure --enable-fuzz --with-sanitizers=address,fuzzer,undefined --without-gui --disable-wallet --disable-stacktraces && make -j10

bls_ies — ✅ PASS

100,000 runs in 14 seconds. No crashes, no assertion failures, no sanitizer errors.

bls_operations⚠️ PASS with LeakSanitizer finding

Short runs (1,000 runs): clean, no issues.
Long runs (60s campaign): LeakSanitizer reports a memory leak in BLS key vector operations.

The leak appears to be in libdashbls internals (std::vector<CBLSSecretKey>::push_back → realloc path), not in the fuzz harness. This is a pre-existing leak in the BLS library, not introduced by this PR. The fuzz target successfully surfaces it for investigation.

Context

Part of the Dash Core Fuzzing Initiative — Phase 3 (Functional Fuzz Targets). BLS operations are priority #1 in Phase 3 because they are consensus-critical: every ChainLock, InstantSend lock, and LLMQ commitment depends on BLS signatures.

Related PRs:

Add two new fuzz targets for Dash-specific BLS cryptographic operations:

bls_operations: Fuzzes BLS key generation, signing, verification,
aggregation (pubkeys, signatures, secret keys), threshold operations
(key shares, signature recovery), DH key exchange, and aggregated
signature verification. Tests both legacy and basic BLS schemes.

bls_ies: Fuzzes BLS Integrated Encryption Scheme operations including
CBLSIESEncryptedBlob and CBLSIESMultiRecipientBlobs decrypt with
fuzzed inputs, and encrypt-then-decrypt roundtrip with matching keys.

Both targets carefully filter fuzzed inputs to avoid UB from accessing
invalid BLS object internals (e.g., AggregateInsecure and
VerifySecureAggregated access .impl without validity checks).

Part of the Dash Core Fuzzing Initiative (Phase 3).
@coderabbitai
Copy link

coderabbitai bot commented Feb 22, 2026

Warning

Rate limit exceeded

@thepastaclaw has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 4 minutes and 36 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

Walkthrough

A new fuzz test source is added to the build and a new fuzz test file implements comprehensive fuzzing for BLS and IES code paths. The file provides helpers to construct fuzzed CBLSSecretKey, CBLSPublicKey, CBLSSignature, and uint256 values, an initialization function that calls BLSInit(), and two fuzz targets: one exercising key generation, signing, verification, aggregation, threshold schemes, and DH-derived operations, and another exercising CBLSIES* serialization, encryption, and decryption flows with fuzzed inputs.

Sequence Diagram(s)

sequenceDiagram
    participant Fuzz as Fuzz Harness
    participant Init as BLSInit
    participant BLS as BLS Library
    participant IES as IES Module
    Fuzz->>Init: call initialize_bls_operations()
    Init->>BLS: BLSInit()
    Fuzz->>BLS: MakeSecretKey / MakePublicKey / MakeSignature / MakeHash
    alt bls_operations flow
        Fuzz->>BLS: KeyGen / Sign
        BLS-->>Fuzz: Signature
        Fuzz->>BLS: Verify / AggregateKeys / AggregateSigs / ThresholdOps
        BLS-->>Fuzz: Verification results / Aggregated blobs
    end
    alt bls_ies flow
        Fuzz->>IES: Deserialize CBLSIESEncryptedBlob / MultiRecipientBlobs
        IES-->>Fuzz: Parsed blobs
        Fuzz->>IES: Decrypt (single / multi) / Encrypt roundtrip
        IES-->>Fuzz: Plaintext / Re-encrypted blobs
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: adding two new fuzz targets (bls_operations and bls_ies) for BLS operations and IES encryption testing.
Description check ✅ Passed The description is comprehensive and directly related to the changeset, providing detailed context on the new fuzz targets, their functionality, validation results, and integration with the Dash Core Fuzzing Initiative.
Docstring Coverage ✅ Passed Docstring coverage is 80.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@thepastaclaw thepastaclaw changed the title test(fuzz): add BLS operations and IES encryption fuzz targets test: add BLS operations and IES encryption fuzz targets Feb 23, 2026
Required for clang-format CI enforcement on Dash-specific files.
@thepastaclaw
Copy link
Author

@coderabbitai review

@coderabbitai
Copy link

coderabbitai bot commented Feb 23, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

CBLSSecretKey MakeSecretKey(FuzzedDataProvider& fuzzed_data_provider)
{
auto bytes = fuzzed_data_provider.ConsumeBytes<uint8_t>(CBLSSecretKey::SerSize);
bytes.resize(CBLSSecretKey::SerSize);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isn't this resize redundant? don't we consume the amount requested above?

src/stats/*.h
src/test/block_reward_reallocation_tests.cpp
src/test/bls_tests.cpp
src/test/fuzz/bls_operations.cppsrc/test/bls_tests.cpp
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

missing newlines / corrupted

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@test/util/data/non-backported.txt`:
- Line 53: The entry "src/test/fuzz/bls_operations.cppsrc/test/bls_tests.cpp" is
a concatenated invalid path; split it into two separate lines
"src/test/fuzz/bls_operations.cpp" and "src/test/bls_tests.cpp" in
test/util/data/non-backported.txt, placing "src/test/fuzz/bls_operations.cpp" in
the alphabetically correct spot (after the existing src/test/evo* entries) so
clang-format picks up the new fuzz target and preserve the existing
src/test/bls_tests.cpp entry.

@thepastaclaw
Copy link
Author

Re: missing newlines — fixed in 4ac72a0, pushed right around when you commented.

Re: resize redundancy on the ConsumeBytes result — it's not redundant. FuzzedDataProvider::ConsumeBytes(n) returns up to n bytes — when the fuzzer's input data is exhausted mid-call, it returns fewer bytes than requested. The resize(SerSize) zero-pads to ensure we always pass exactly the right number of bytes to the BLS constructor, regardless of how much fuzz data was left.

Copy link
Member

@PastaPastaPasta PastaPastaPasta left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

utACK 4ac72a0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants