Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: deglobalization of bls_legacy_scheme 3/N #6508

Open
wants to merge 17 commits into
base: develop
Choose a base branch
from

Conversation

knst
Copy link
Collaborator

@knst knst commented Dec 25, 2024

Issue being fixed or feature implemented

Many usages of CBLS{Signature,PrivateKey,PublicKey} assume using global variable, even if it can be specified explicitly in some situations.

These over-usages of bls::bls_legacy_scheme are blocker for changing buried height of activation of fork V19 on Regtest.
This PR helps unblock changing v19 height on RegTest, see: #6511

Prior improvements for BLS: #5443

What was done?

This PR does:

  • fixes Undefined Behavior in rpc protx register_legacy, protx register_fund_legacy, protx resiter_prepare_legacy, protx update_registrar_legacy
  • drop flag "is legacy" from secret key initialization and serialization (as it has no difference)
  • enforce specifying legacy flag to bls functions Sign, ToByteVector and in a helper SignSpecialTxPayloadByHash
  • removed unused methods from bls_ies.h and optimized headers usages
  • enforce p2p message mnauth to use Basic BLS scheme
  • enforce using flag legacy in RPC bls generate and bls fromsecret instead guessing which one user want based on v19 activation status.

How Has This Been Tested?

Run unit and functional tests; update testing framework test_framework.py to use _legacy RPCs which has been ignored before.

Reindex testnet src/qt/dash-qt -reindex -testnet -assumevalid=0 - SUCCEED
Reindex mainnet src/qt/dash-qt -reindex -assumevalid=0 - SUCCEED

Breaking Changes

On RegTest RPC: bls generate, bls fromsecret should pass flag is_legacy for pre-v19 blocks
On RegTest RPC: protx register_legacy, protx register_fund_legacy, protx register_prepare_legacy, protx update_registrar_legacy should be used in pre-v19 blocks.

Checklist:

  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have added or updated relevant unit/integration/functional/e2e tests
  • I have made corresponding changes to the documentation
  • I have assigned this pull request to a milestone

@knst knst added this to the 22.1 milestone Dec 25, 2024
Copy link

coderabbitai bot commented Dec 25, 2024

Walkthrough

The provided changes represent a comprehensive update to the BLS (Boneh-Lynn-Shacham) cryptographic implementation across multiple components of the codebase. The primary modification involves introducing a new parameter to signature generation and verification methods, which allows explicit control over the legacy BLS signing scheme.

The changes span numerous files, including core cryptographic implementations, RPC interfaces, test frameworks, and consensus-related modules. Key modifications include updating method signatures for Sign and VerifyInsecure methods, removing legacy-specific methods, and adding conditional logic to handle different BLS signing schemes based on soft fork activation status.

These updates aim to provide more granular control over the BLS signature generation process, allowing developers and the system to explicitly specify whether to use the legacy or basic signing scheme. The changes are designed to maintain backward compatibility while introducing more flexible cryptographic operations across the system.

Tip

CodeRabbit's docstrings feature is now available as part of our Early Access Program! Simply use the command @coderabbitai generate docstrings to have CodeRabbit automatically generate docstrings for your pull request. We would love to hear your feedback on Discord.


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR. (Beta)
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

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: 3

🧹 Nitpick comments (8)
src/bls/bls_ies.cpp (1)

Line range hint 12-21: **Consider adding error-handling for partial encryption **

The function returns false only if Encrypt() writes fewer bytes than requested, but it doesn't provide finer-grained error details. Consider returning or logging more nuanced information (e.g., AES errors) to aid in debugging and to avoid silent failures.

src/bls/bls.h (2)

261-265: **Clarify forced non-legacy behavior in constructor **

The constructor always calls SetByteVector(vecBytes, false), implying a non-legacy scheme. Consider renaming or documenting this logic so that callers are aware they cannot override the legacy mode here.


331-334: **Parameter naming suggestion **

is_serialized_legacy might be more readable as something like useLegacyFormat. The current name is correct but a shorter, more direct name can improve clarity for new contributors.

src/test/evo_mnhf_tests.cpp (1)

63-66: Explicit toggling of legacy usage in test
Setting const bool use_legacy{false} and passing it to Sign/VerifyInsecure properly demonstrates the new parameter’s usage. Consider adding a separate test with true to ensure coverage of the legacy path.

src/llmq/dkgsessionmgr.h (1)

16-19: Consider adding clarifying documentation for new forward declarations
These forward declarations are presumably used to manage encrypted contributions, yet there’s no explanatory comment indicating their intended usage or ownership. Consider adding a short docstring to clarify their purpose and how they integrate into the DKG session.

src/test/bls_tests.cpp (1)

27-28: Check for concurrency and global state usage.
Both calls rely on modifying the global bls::bls_legacy_scheme. If tests are run in parallel, consider potential side effects from changing this global state across different test threads.

src/test/evo_deterministicmns_tests.cpp (1)

174-174: Consider adding coverage for signature migrations.
To avoid regressions, add or expand tests that confirm correct behavior when toggling between legacy and non-legacy BLS schemes.

test/functional/test_framework/test_framework.py (1)

1306-1307: Consider extracting repeated v19 check and BLS generation into a helper function.
You call softfork_active(self.nodes[0], 'v19') and handle BLS generation similarly in multiple places. This duplication could be avoided and made more maintainable with a dedicated helper method like get_bls_keypair(v19_active).

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2bd4703 and 03c8cc1.

📒 Files selected for processing (27)
  • src/bench/bls.cpp (3 hunks)
  • src/bls/bls.cpp (0 hunks)
  • src/bls/bls.h (2 hunks)
  • src/bls/bls_ies.cpp (4 hunks)
  • src/bls/bls_ies.h (1 hunks)
  • src/bls/bls_worker.cpp (1 hunks)
  • src/coinjoin/coinjoin.cpp (2 hunks)
  • src/evo/assetlocktx.h (1 hunks)
  • src/evo/mnauth.cpp (3 hunks)
  • src/evo/providertx.h (1 hunks)
  • src/evo/specialtxman.cpp (2 hunks)
  • src/llmq/dkgsession.cpp (5 hunks)
  • src/llmq/dkgsession.h (1 hunks)
  • src/llmq/dkgsessionmgr.cpp (1 hunks)
  • src/llmq/dkgsessionmgr.h (1 hunks)
  • src/llmq/signing_shares.cpp (1 hunks)
  • src/masternode/node.cpp (0 hunks)
  • src/masternode/node.h (0 hunks)
  • src/rpc/evo.cpp (9 hunks)
  • src/rpc/governance.cpp (1 hunks)
  • src/test/bls_tests.cpp (10 hunks)
  • src/test/evo_deterministicmns_tests.cpp (2 hunks)
  • src/test/evo_mnhf_tests.cpp (1 hunks)
  • src/test/rpc_tests.cpp (3 hunks)
  • src/validation.cpp (1 hunks)
  • test/functional/feature_dip3_deterministicmns.py (6 hunks)
  • test/functional/test_framework/test_framework.py (4 hunks)
💤 Files with no reviewable changes (3)
  • src/bls/bls.cpp
  • src/masternode/node.cpp
  • src/masternode/node.h
✅ Files skipped from review due to trivial changes (2)
  • src/evo/assetlocktx.h
  • src/rpc/governance.cpp
🔇 Additional comments (55)
src/bls/bls_ies.cpp (3)

47-49: **Validate consistent use of the truncated BLS key as a 32-byte symmetric key **

Here, the code converts the public key into a byte vector, then truncates it to 32 bytes. Confirm this key derivation follows a secure practice (e.g., applying a KDF). Also ensure that future code reading expects only the first 32 bytes.


83-85: **Same key truncation logic as above **


100-102: **Same key truncation logic as above **

src/bls/bls_ies.h (1)

11-15: **Documentation clarity **

The added comment clearly states that the basic scheme is assumed for all masternodes and that serialization uses the Basic Scheme. This is a good step toward preventing misuse or confusion about which scheme is in effect.

src/evo/specialtxman.cpp (2)

Line range hint 209-215: **Atomic legacy scheme toggle **

Switching bls_legacy_scheme to false here relies on std::atomic for thread safety. Verify that no race conditions arise if multiple threads process blocks concurrently. Also confirm that flipping the global scheme immediately is safe for all ongoing operations.


Line range hint 230-236: **Reverting to legacy scheme on block undo **

Reverting bls_legacy_scheme when undoing the activation block is logical, but confirm that reorgs or partial replays won't lead to inconsistent scheme states. Consider how concurrency or partial failures might affect this toggle.

src/llmq/dkgsessionmgr.cpp (1)

11-11: **Header inclusion check **

Including <bls/bls_ies.h> is appropriate for the newly introduced encryption methods. Confirm no redundant includes if performance or compile-times become concerns.

test/functional/feature_dip3_deterministicmns.py (1)

214-214: Conditionally switch registrar update method based on softfork state
Using 'v19' activation status to decide between update_registrar and update_registrar_legacy is a neat solution. Please ensure you test both branches in your functional tests, so that the older path is not overlooked.

src/llmq/dkgsession.cpp (7)

87-88: Use of DeploymentActiveAfter to determine legacy BLS usage
Initializing m_use_legacy_bls with !DeploymentActiveAfter(...) is clear for deciding which scheme to use. However, ensure that reorg or varying block heights do not require a dynamic check or re-evaluation of this field. Consider verifying or documenting that the chosen block index won’t shift during runtime if a reorg happens.


219-219: Consistent signature generation with legacy parameter
Replacing direct calls to Sign(qc.GetSignHash()) with Sign(..., m_use_legacy_bls) aligns well with the global toggle. This looks correct.


531-531: Usage of legacy BLS toggle
Continuing the same pattern of calling Sign(...) with m_use_legacy_bls is consistent and straightforward.


725-725: Signature assignment with the correct scheme
Utilizing m_use_legacy_bls for qj.sig helps maintain uniform handling of the BLS scheme.


1015-1017: Potential scheme mismatch
Here, qc.sig is signed with use_legacy_bls, while qc.quorumSig is signed via bls::bls_legacy_scheme.load(). Verify that these two scheme indicators cannot drift out of sync in certain edge cases. A mismatch could produce invalid signatures.


1020-1022: Index bound check when mutating signature buffer
Modifying buf[5]++ helps simulate a corrupted signature. Ensure this index is always safe (e.g., signature length ≥ 6 bytes).


1024-1026: Quorum signature corruption simulation
Similar concern with buf[5]++. Confirm that the signature is always large enough so this index never goes out of range.

src/rpc/evo.cpp (5)

200-205: Hardcoding modOrder flag to false
Previously, there was a parameter for the secret key scheme. Now we default to false within ParseBLSSecretKey. Although simpler, confirm that ignoring the modOrder parameter does not lead to incorrect behavior when dealing with certain BLS keys.


310-317: Introducing the use_legacy option for special TX signing
Adding the bool use_legacy parameter clarifies which scheme is used. Ensure code that calls SignSpecialTxPayloadByHash thoroughly sets this flag and that tests cover both new and legacy paths.


657-657: Extracting use_legacy from incoming parameter
Defining use_legacy by specific_legacy_bls_scheme is straightforward. Double-check if the rest of the code references only use_legacy so no mismatch arises.


Line range hint 1306-1307: Dynamic selection of BLS generation based on v19
Conditionally calling bls('generate') or bls('generate', True) looks correct. Ensure you have coverage for both the pre- and post-v19 scenarios in your tests.


Line range hint 1340-1340: Register vs. register_legacy usage
Using 'register' if v19_active else 'register_legacy' is consistent with the approach throughout the codebase. Please confirm that any edge case around the activation transition is tested.

src/evo/mnauth.cpp (3)

54-55: Confirm that forcing basic BLS does not impact backward compatibility
By invoking mn_activeman.Sign(signHash, false), you're mandating basic BLS for all nodes. Ensure that no remaining code paths require a legacy signature or a transition phase for older nodes.


90-91: Usage of mnauth.sig.ToString(false)
The signature stringification now explicitly defaults to "basic BLS" output, which is consistent with the new scheme. No issues found, but ensure logs remain human-readable and clearly indicate the scheme used.


117-117: Verify that “false” is correct for legacy parameter
You’ve hard-coded false for this VerifyInsecure call, which aligns with a basic BLS scheme. Confirm that this is correct for all p2p interactions you expect during MNAUTH.

src/bench/bls.cpp (4)

32-32: Signing with the second parameter set to false
You are now specifying the signing scheme (basic vs. legacy). Looks consistent with the updated method signature. No correctness issue found.


37-37: Generating invalid signatures
Changing to s.Sign(msgHashes[i], false) clarifies you’re using the basic BLS scheme even for invalid signatures. No problem found here.


74-75: Consistent usage of false in signature creation
Both lines use the updated parameter to enforce basic BLS. This is coherent with the rest of the code changes.


92-92: Signing in benchmark test
Switching to secKey.Sign(hash, false) allows verifying performance under the new scheme. Behavior appears correct.

src/llmq/dkgsession.h (1)

291-291: Ensure proper initialization of the new flag.
The new bool m_use_legacy_bls field should be explicitly assigned in the constructor or via initialization to avoid any uninitialized state issues.

src/test/bls_tests.cpp (14)

47-47: No issue found.
The signature logic appears straightforward, and test coverage is sufficient for this line.


66-66: Comment clarity.
The added comment is accurate regarding the second parameter usage in SetHexStr. No further changes needed.


70-71: Validating hex strings.
These checks properly ensure the string is valid hexadecimal. The error handling is correct.


75-76: Coverage of short hex string edge case.
The test scenario for short hex strings is appropriate, and the error condition is verified.


78-80: Coverage of long hex string edge case.
Ensures that overly long strings are handled correctly. No changes needed.


105-105: Signature creation.
The invocation of Sign with the legacy_scheme flag is consistent with the broader changes to handle legacy vs. basic BLS scheme.


147-147: Signature verification coverage.
Signing and verifying with aggregated keys is properly tested.


173-173: Aggregation logic verification.
This line is part of the process to aggregate signatures. Looks correct.


224-224: Secure aggregation approach.
Use of Sign and AggregateSecure is logically consistent.


267-267: Capturing global scheme state.
Capturing the current BLS scheme in a local variable is valid, ensuring consistency for subsequent calls.


274-274: Consistency in creating signatures.
This call uses the newly introduced legacy_scheme parameter. No issues noted.


280-280: Alternate signature creation.
Switching to a different key ensures negative test coverage. Looks correct.


385-385: Threshold signing.
The introduced parameter is consistent with the rest of the code.


402-402: Recovering threshold shares.
Checks each share’s validity, with consistent usage of the legacy scheme flag.

src/coinjoin/coinjoin.cpp (2)

65-65: Confirm consistent signing approach.
This verifies signatures with false for the second parameter, matching the approach in Sign(...). Ensure no mismatch arises elsewhere.


104-104: Consistent verification parameter.
Again, passing false to match non-legacy usage is correct for these checks.

src/test/rpc_tests.cpp (5)

546-546: Updated expectation for default scheme.
The test verifying the scheme as "basic" aligns with the new BLS default.


558-560: Testing bls fromsecret with basic scheme.
Ensures the returned public key matches the basic scheme's expectation, confirming functional correctness.


566-566: Zero argument implies basic scheme.
Consistent with the changes that default to is_legacy = false.


579-579: Checking legacy scheme.
This call confirms that passing 1 triggers a legacy BLS signature.


582-582: Verifying no second parameter implies basic.
Aligned with default scheme expectations.

src/bls/bls_worker.cpp (1)

765-765: Explicitly specifying the scheme looks correct.
The call to secKey.Sign(msgHash, bls::bls_legacy_scheme.load()) clarifies the use of the legacy scheme for BLS signatures and aligns with the broader refactoring.

src/test/evo_deterministicmns_tests.cpp (1)

135-135: Validate consistent usage of the legacy scheme.
Including the legacy scheme parameter is correct. Verify that all dependent test cases account for the newly explicit bls::bls_legacy_scheme usage to prevent any signature mismatches.

src/llmq/signing_shares.cpp (1)

1544-1544: Ensure legacy scheme parameter is consistently applied.
The updated signature creation with bls::bls_legacy_scheme.load() is clear. Confirm calls throughout the codebase also specify this scheme if intended, preventing mismatched configurations.

test/functional/test_framework/test_framework.py (3)

1340-1340: Validate usage of 'register' vs 'register_legacy' for future-proofing.
The inline ternary is appropriate here, but double-check that any interaction with other code (like future forks) won’t break if the legacy or non-legacy approach changes again. This is especially relevant given the reliance on softfork activation.


1422-1422: Ensure test coverage for the 'register_fund' vs 'register_fund_legacy' call.
It is crucial to confirm that the new logic for choosing between the two registration methods addresses corner cases, including incomplete migrations and wallet states.


1425-1425: Check consistency of the 'register' vs 'register_legacy' calls.
Using the inline conditional for different protx commands looks correct, but validating in integration tests that each path behaves as expected post-v19 is recommended.

src/evo/providertx.h Show resolved Hide resolved
src/validation.cpp Outdated Show resolved Hide resolved
Old name 'use legacy scheme' is incorrect, because this flag means 'is basic scheme' used
@knst knst force-pushed the fix-no-legacy-bls-secret branch from 03c8cc1 to 3e1d375 Compare December 25, 2024 09:25
@knst knst changed the title refactor: deglobalization of bls_legacy_scheme 3/N refactor: deglobalization of bls_legacy_scheme 3/N Dec 25, 2024
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

🧹 Nitpick comments (4)
src/llmq/dkgsessionmgr.cpp (1)

Line range hint 300-340: Consider optimizing member lookup in GetEncryptedContributions

The linear search for member index could be optimized for better performance, especially with larger quorums.

Consider using a hash map for O(1) member lookup:

 bool CDKGSessionManager::GetEncryptedContributions(Consensus::LLMQType llmqType, const CBlockIndex* pQuorumBaseBlockIndex, const std::vector<bool>& validMembers, const uint256& nProTxHash, std::vector<CBLSIESEncryptedObject<CBLSSecretKey>>& vecRet) const
 {
     auto members = utils::GetAllQuorumMembers(llmqType, m_dmnman, pQuorumBaseBlockIndex);
 
     vecRet.clear();
     vecRet.reserve(members.size());
 
+    std::unordered_map<uint256, size_t> memberIndices;
+    for (const auto i : irange::range(members.size())) {
+        memberIndices[members[i]->proTxHash] = i;
+    }
+
+    auto it = memberIndices.find(nProTxHash);
+    if (it == memberIndices.end()) {
-    size_t nRequestedMemberIdx{std::numeric_limits<size_t>::max()};
-    for (const auto i : irange::range(members.size())) {
-        // cppcheck-suppress useStlAlgorithm
-        if (members[i]->proTxHash == nProTxHash) {
-            nRequestedMemberIdx = i;
-            break;
-        }
-    }
-    if (nRequestedMemberIdx == std::numeric_limits<size_t>::max()) {
         LogPrint(BCLog::LLMQ, "CDKGSessionManager::%s -- not a member, nProTxHash=%s\n", __func__, nProTxHash.ToString());
         return false;
     }
+    size_t nRequestedMemberIdx = it->second;
src/llmq/dkgsession.cpp (1)

1015-1017: Remove unnecessary local variable.

The local variable use_legacy_bls is redundant as m_use_legacy_bls can be used directly.

Apply this diff to simplify the code:

-    const bool use_legacy_bls = m_use_legacy_bls;
-    qc.sig = m_mn_activeman->Sign(commitmentHash, use_legacy_bls);
+    qc.sig = m_mn_activeman->Sign(commitmentHash, m_use_legacy_bls);
src/bls/bls_ies.h (2)

11-15: Documentation improvement suggestion

The added documentation clearly states the Basic scheme requirement. Consider enhancing it with:

  1. A reference to the V19 fork context
  2. Potential migration implications for existing users

Here's a suggested enhancement:

 /**
  * All objects in this module working from assumption that basic scheme is
  * available on all masternodes. Serialization of public key for Encrypt and
  * Decrypt by bls_ies.h done using Basic Scheme.
+ *
+ * Note: This requirement is part of the V19 fork changes. Systems using legacy
+ * scheme need to migrate to basic scheme before the fork activation.
  */

11-15: Migration strategy advice for V19 fork

The consistent enforcement of Basic BLS scheme is a breaking change that requires careful migration planning:

  1. Consider adding a migration utility to help users transition from legacy to Basic scheme
  2. Add runtime checks during the transition period to detect and warn about legacy scheme usage
  3. Consider adding version detection in the serialization code to maintain backward compatibility until V19 activation

Would you like me to propose a detailed migration strategy or open an issue to track this work?

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 03c8cc1 and 3e1d375.

📒 Files selected for processing (27)
  • src/bench/bls.cpp (3 hunks)
  • src/bls/bls.cpp (0 hunks)
  • src/bls/bls.h (2 hunks)
  • src/bls/bls_ies.cpp (4 hunks)
  • src/bls/bls_ies.h (1 hunks)
  • src/bls/bls_worker.cpp (1 hunks)
  • src/coinjoin/coinjoin.cpp (2 hunks)
  • src/evo/assetlocktx.h (1 hunks)
  • src/evo/mnauth.cpp (3 hunks)
  • src/evo/providertx.h (4 hunks)
  • src/evo/specialtxman.cpp (2 hunks)
  • src/llmq/dkgsession.cpp (5 hunks)
  • src/llmq/dkgsession.h (1 hunks)
  • src/llmq/dkgsessionmgr.cpp (1 hunks)
  • src/llmq/dkgsessionmgr.h (1 hunks)
  • src/llmq/signing_shares.cpp (1 hunks)
  • src/masternode/node.cpp (0 hunks)
  • src/masternode/node.h (0 hunks)
  • src/rpc/evo.cpp (9 hunks)
  • src/rpc/governance.cpp (1 hunks)
  • src/test/bls_tests.cpp (10 hunks)
  • src/test/evo_deterministicmns_tests.cpp (2 hunks)
  • src/test/evo_mnhf_tests.cpp (1 hunks)
  • src/test/rpc_tests.cpp (3 hunks)
  • src/validation.cpp (1 hunks)
  • test/functional/feature_dip3_deterministicmns.py (6 hunks)
  • test/functional/test_framework/test_framework.py (4 hunks)
💤 Files with no reviewable changes (3)
  • src/masternode/node.h
  • src/bls/bls.cpp
  • src/masternode/node.cpp
🚧 Files skipped from review as they are similar to previous changes (20)
  • src/test/rpc_tests.cpp
  • src/evo/assetlocktx.h
  • src/rpc/governance.cpp
  • src/test/evo_deterministicmns_tests.cpp
  • src/llmq/dkgsessionmgr.h
  • src/coinjoin/coinjoin.cpp
  • src/bls/bls_worker.cpp
  • src/test/evo_mnhf_tests.cpp
  • src/llmq/dkgsession.h
  • src/evo/specialtxman.cpp
  • test/functional/feature_dip3_deterministicmns.py
  • src/evo/mnauth.cpp
  • src/bench/bls.cpp
  • src/rpc/evo.cpp
  • src/evo/providertx.h
  • src/bls/bls.h
  • src/validation.cpp
  • src/test/bls_tests.cpp
  • src/llmq/signing_shares.cpp
  • test/functional/test_framework/test_framework.py
🔇 Additional comments (11)
src/llmq/dkgsessionmgr.cpp (3)

11-11: LGTM: BLS IES header inclusion

The addition of bls/bls_ies.h aligns with the PR's objective to refactor the BLS legacy scheme and supports the new encrypted contributions functionality.


Line range hint 250-253: LGTM: WriteEncryptedContributions implementation

The method follows the established pattern of other Write* methods in the class and maintains proper const correctness.


Line range hint 28-30: LGTM: Clean integration of encrypted contributions

The new encrypted contributions are properly integrated into the existing cleanup mechanism, maintaining backward compatibility and following the established patterns for database operations.

Also applies to: 400-450

src/llmq/dkgsession.cpp (4)

87-88: LGTM: Proper initialization of BLS scheme based on V19 deployment status.

The initialization of m_use_legacy_bls correctly determines the BLS scheme based on V19 deployment status, which aligns with the PR objectives.


219-219: LGTM: Consistent BLS scheme usage in contribution signatures.

The signature generation now correctly uses the instance-specific BLS scheme flag, ensuring consistency with V19 deployment status.


531-531: LGTM: Consistent BLS scheme usage in complaint signatures.

The signature generation now correctly uses the instance-specific BLS scheme flag, ensuring consistency with V19 deployment status.


725-725: LGTM: Consistent BLS scheme usage in justification signatures.

The signature generation now correctly uses the instance-specific BLS scheme flag, ensuring consistency with V19 deployment status.

src/bls/bls_ies.cpp (4)

12-12: LGTM: Improved type safety in EncryptBlob signature

The change from template parameter to specific vector type improves type safety and makes the interface more explicit.


83-83: LGTM: Consistent Basic scheme usage

The change maintains consistency with the Basic BLS scheme usage for key derivation across the codebase.


100-100: LGTM: Symmetric Basic scheme usage in encryption/decryption

The change ensures symmetric behavior between encryption and decryption operations by consistently using the Basic scheme.


47-47: ⚠️ Potential issue

Verify symmetric key derivation changes

The change to pk.ToByteVector(false) enforces the Basic BLS scheme for key derivation. This is a breaking change that affects symmetric key generation.

Run this script to verify consistent usage across the codebase:

✅ Verification successful

Let me analyze the search results and generate additional verification scripts to check the BLS-related code.


Let me search for more specific BLS IES encryption/decryption related code.


Let me check one more aspect to verify the consistency of BLS scheme usage.


Verified: BLS IES key derivation consistently uses Basic scheme

The change to pk.ToByteVector(false) in CBLSIESEncryptedBlob::Decrypt is consistent with the codebase's BLS IES implementation:

  • All BLS IES encryption/decryption operations consistently use ToByteVector(false) for symmetric key derivation
  • The DHKeyExchange operation used in the key derivation process is consistently implemented across the codebase
  • No legacy scheme usage was found in BLS IES related code
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for any remaining unspecified ToByteVector calls in BLS-related code
# that might need the explicit legacy parameter

# Search for ToByteVector calls without explicit legacy parameter
rg "ToByteVector\(\s*\)" --type cpp

# Search for all ToByteVector calls to compare
rg "ToByteVector\(" --type cpp

Length of output: 30618


Script:

#!/bin/bash
# Search for BLS-related ToByteVector calls to verify consistency
rg "ToByteVector\(.*\)" --type cpp src/bls/

# Search for BLS key derivation related code
ast-grep --pattern 'CBLSPublicKey::ToByteVector($_)'

Length of output: 1034


Script:

#!/bin/bash
# Search for BLS IES encryption/decryption implementation
rg -A 10 "CBLSIESEncryptedBlob::(Encrypt|Decrypt)" --type cpp

# Search for BLS IES tests
rg "TEST.*bls.*ies" -i --type cpp

Length of output: 1113


Script:

#!/bin/bash
# Search for all DHKeyExchange calls to verify BLS scheme consistency
rg "DHKeyExchange" --type cpp -B 2 -A 2

# Search for other BLS IES encryption/decryption methods
rg "CBLSIESEncryptedBlob::" --type cpp -B 2 -A 2

Length of output: 2342

src/llmq/dkgsession.cpp Outdated Show resolved Hide resolved
@knst knst marked this pull request as draft December 25, 2024 13:12
@knst knst force-pushed the fix-no-legacy-bls-secret branch 4 times, most recently from 615a252 to 5189807 Compare December 26, 2024 16:01
knst added a commit to knst/dash that referenced this pull request Dec 26, 2024
The implementation of RPC has been refactored in bitcoin significantly with using RPCHelpMan,
see multiple PR, such as bitcoin#1853, bitcoin#19528, etc

Backporting them and appliying same refactoring to Dash Core caused undefined behaviour, particularly dashpay#6072

For example, in this code the local variable `use_legacy` will be used after `protx_update_registrar_wrapper`,
when executor will be called.

    static RPCHelpMan protx_update_registrar_wrapper(const bool use_legacy)
    {
        std::string rpc_name = use_legacy ? "update_registrar_legacy" : "update_registrar";
        std::string rpc_full_name = std::string("protx ").append(rpc_name);
        std::string pubkey_operator = use_legacy ? "\"0532646990082f4fd639f90387b1551f2c7c39d37392cb9055a06a7e85c1d23692db8f87f827886310bccc1e29db9aee\"" : "\"8532646990082f4fd639f90387b1551f2c7c39d37392cb9055a06a7e85c1d23692db8f87f827886310bccc1e29db9aee\"";
        std::string rpc_example = rpc_name.append(" \"0123456701234567012345670123456701234567012345670123456701234567\" ").append(pubkey_operator).append(" \"" + EXAMPLE_ADDRESS[1] + "\"");
        return RPCHelpMan{rpc_full_name,
        <...>
        RPCResult{
            RPCResult::Type::STR_HEX, "txid", "The transaction id"
        },
        RPCExamples{
            HelpExampleCli("protx", rpc_example)
        },
        [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
    {
        <...>
        ptx.nVersion = specific_legacy_bls_scheme ? CProUpRegTx::LEGACY_BLS_VERSION : CProUpRegTx::BASIC_BLS_VERSION; <<<<---- THERE IS UB

It can be easy tested by adding debug logs to log string, for example rpc_full_name at the moment of call of executor has been during run:

    2024-12-26T16:10:15Z rpc full name: 'r,ߧzu\x00\x00����m���istrar_legacy'

This PR fixes multiple unexplainable random failures which had happen only for `tsan` build or for only `ubsan` build during debuggin dashpay#6508
and depends only on code revision.
knst added a commit to knst/dash that referenced this pull request Dec 26, 2024
The implementation of RPC has been refactored in bitcoin significantly with using RPCHelpMan,
see multiple PR, such as bitcoin#1853, bitcoin#19528, etc

Backporting them and appliying same refactoring to Dash Core caused undefined behaviour, particularly dashpay#6072

For example, in this code the local variable `use_legacy` will be used after `protx_update_registrar_wrapper`,
when executor will be called.

    static RPCHelpMan protx_update_registrar_wrapper(const bool use_legacy)
    {
        std::string rpc_name = use_legacy ? "update_registrar_legacy" : "update_registrar";
        std::string rpc_full_name = std::string("protx ").append(rpc_name);
        std::string pubkey_operator = use_legacy ? "\"0532646990082f4fd639f90387b1551f2c7c39d37392cb9055a06a7e85c1d23692db8f87f827886310bccc1e29db9aee\"" : "\"8532646990082f4fd639f90387b1551f2c7c39d37392cb9055a06a7e85c1d23692db8f87f827886310bccc1e29db9aee\"";
        std::string rpc_example = rpc_name.append(" \"0123456701234567012345670123456701234567012345670123456701234567\" ").append(pubkey_operator).append(" \"" + EXAMPLE_ADDRESS[1] + "\"");
        return RPCHelpMan{rpc_full_name,
        <...>
        RPCResult{
            RPCResult::Type::STR_HEX, "txid", "The transaction id"
        },
        RPCExamples{
            HelpExampleCli("protx", rpc_example)
        },
        [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
    {
        <...>
        ptx.nVersion = specific_legacy_bls_scheme ? CProUpRegTx::LEGACY_BLS_VERSION : CProUpRegTx::BASIC_BLS_VERSION; <<<<---- THERE IS UB

It can be easy tested by adding debug logs to log string, for example rpc_full_name at the moment of call of executor has been during run:

    2024-12-26T16:10:15Z rpc full name: 'r,ߧzu\x00\x00����m���istrar_legacy'

This PR fixes multiple unexplainable random failures which had happen only for `tsan` build or for only `ubsan` build during debuggin dashpay#6508
and depends only on code revision.
@knst knst force-pushed the fix-no-legacy-bls-secret branch from c546b0e to 6add847 Compare December 26, 2024 17:22
knst added a commit to knst/dash that referenced this pull request Dec 26, 2024
The implementation of RPC has been refactored in bitcoin significantly with using RPCHelpMan,
see multiple PR, such as bitcoin#1853, bitcoin#19528, etc

Backporting them and appliying same refactoring to Dash Core caused undefined behaviour, particularly dashpay#6072

For example, in this code the local variable `use_legacy` will be used after `protx_update_registrar_wrapper`,
when executor will be called.

    static RPCHelpMan protx_update_registrar_wrapper(const bool use_legacy)
    {
        std::string rpc_name = use_legacy ? "update_registrar_legacy" : "update_registrar";
        std::string rpc_full_name = std::string("protx ").append(rpc_name);
        std::string pubkey_operator = use_legacy ? "\"0532646990082f4fd639f90387b1551f2c7c39d37392cb9055a06a7e85c1d23692db8f87f827886310bccc1e29db9aee\"" : "\"8532646990082f4fd639f90387b1551f2c7c39d37392cb9055a06a7e85c1d23692db8f87f827886310bccc1e29db9aee\"";
        std::string rpc_example = rpc_name.append(" \"0123456701234567012345670123456701234567012345670123456701234567\" ").append(pubkey_operator).append(" \"" + EXAMPLE_ADDRESS[1] + "\"");
        return RPCHelpMan{rpc_full_name,
        <...>
        RPCResult{
            RPCResult::Type::STR_HEX, "txid", "The transaction id"
        },
        RPCExamples{
            HelpExampleCli("protx", rpc_example)
        },
        [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
    {
        <...>
        ptx.nVersion = specific_legacy_bls_scheme ? CProUpRegTx::LEGACY_BLS_VERSION : CProUpRegTx::BASIC_BLS_VERSION; <<<<---- THERE IS UB

It can be easy tested by adding debug logs to log string, for example rpc_full_name at the moment of call of executor has been during run:

    2024-12-26T16:10:15Z rpc full name: 'r,ߧzu\x00\x00����m���istrar_legacy'

This PR fixes multiple unexplainable random failures which had happen only for `tsan` build or for only `ubsan` build during debuggin dashpay#6508
and depends only on code revision.
@knst knst force-pushed the fix-no-legacy-bls-secret branch from 6add847 to 5994585 Compare December 26, 2024 17:36
knst added a commit to knst/dash that referenced this pull request Dec 26, 2024
The implementation of RPC has been refactored in bitcoin significantly with using RPCHelpMan,
see multiple PR, such as bitcoin#1853, bitcoin#19528, etc

Backporting them and appliying same refactoring to Dash Core caused undefined behaviour, particularly dashpay#6072

For example, in this code the local variable `use_legacy` will be used after `protx_update_registrar_wrapper`,
when executor will be called.

    static RPCHelpMan protx_update_registrar_wrapper(const bool use_legacy)
    {
        std::string rpc_name = use_legacy ? "update_registrar_legacy" : "update_registrar";
        std::string rpc_full_name = std::string("protx ").append(rpc_name);
        std::string pubkey_operator = use_legacy ? "\"0532646990082f4fd639f90387b1551f2c7c39d37392cb9055a06a7e85c1d23692db8f87f827886310bccc1e29db9aee\"" : "\"8532646990082f4fd639f90387b1551f2c7c39d37392cb9055a06a7e85c1d23692db8f87f827886310bccc1e29db9aee\"";
        std::string rpc_example = rpc_name.append(" \"0123456701234567012345670123456701234567012345670123456701234567\" ").append(pubkey_operator).append(" \"" + EXAMPLE_ADDRESS[1] + "\"");
        return RPCHelpMan{rpc_full_name,
        <...>
        RPCResult{
            RPCResult::Type::STR_HEX, "txid", "The transaction id"
        },
        RPCExamples{
            HelpExampleCli("protx", rpc_example)
        },
        [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
    {
        <...>
        ptx.nVersion = specific_legacy_bls_scheme ? CProUpRegTx::LEGACY_BLS_VERSION : CProUpRegTx::BASIC_BLS_VERSION; <<<<---- THERE IS UB

It can be easy tested by adding debug logs to log string, for example rpc_full_name at the moment of call of executor has been during run:

    2024-12-26T16:10:15Z rpc full name: 'r,ߧzu\x00\x00����m���istrar_legacy'

This PR fixes multiple unexplainable random failures which had happen only for `tsan` build or for only `ubsan` build during debuggin dashpay#6508
and depends only on code revision.
@knst knst force-pushed the fix-no-legacy-bls-secret branch from 5994585 to 291aff7 Compare December 26, 2024 19:04
@knst knst marked this pull request as ready for review December 26, 2024 20:21
src/evo/specialtxman.cpp Outdated Show resolved Hide resolved
src/llmq/dkgsession.cpp Outdated Show resolved Hide resolved
knst added 10 commits December 27, 2024 18:00
It also removes unused ToByteVector from CBLSWrapper
…ng based if v19 is activated

Soft fork V19 is activated long time ago, so, basically no changes for mainnet/testnet
The implementation of RPC has been refactored in bitcoin significantly with using RPCHelpMan,
see multiple PR, such as bitcoin#1853, bitcoin#19528, etc

Backporting them and appliying same refactoring to Dash Core caused undefined behaviour, particularly dashpay#6072

For example, in this code the local variable `use_legacy` will be used after `protx_update_registrar_wrapper`,
when executor will be called.

    static RPCHelpMan protx_update_registrar_wrapper(const bool use_legacy)
    {
        std::string rpc_name = use_legacy ? "update_registrar_legacy" : "update_registrar";
        std::string rpc_full_name = std::string("protx ").append(rpc_name);
        std::string pubkey_operator = use_legacy ? "\"0532646990082f4fd639f90387b1551f2c7c39d37392cb9055a06a7e85c1d23692db8f87f827886310bccc1e29db9aee\"" : "\"8532646990082f4fd639f90387b1551f2c7c39d37392cb9055a06a7e85c1d23692db8f87f827886310bccc1e29db9aee\"";
        std::string rpc_example = rpc_name.append(" \"0123456701234567012345670123456701234567012345670123456701234567\" ").append(pubkey_operator).append(" \"" + EXAMPLE_ADDRESS[1] + "\"");
        return RPCHelpMan{rpc_full_name,
        <...>
        RPCResult{
            RPCResult::Type::STR_HEX, "txid", "The transaction id"
        },
        RPCExamples{
            HelpExampleCli("protx", rpc_example)
        },
        [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
    {
        <...>
        ptx.nVersion = specific_legacy_bls_scheme ? CProUpRegTx::LEGACY_BLS_VERSION : CProUpRegTx::BASIC_BLS_VERSION; <<<<---- THERE IS UB

It can be easy tested by adding debug logs to log string, for example rpc_full_name at the moment of call of executor has been during run:

    2024-12-26T16:10:15Z rpc full name: 'r,ߧzu\x00\x00����m���istrar_legacy'

This PR fixes multiple unexplainable random failures which had happen only for `tsan` build or for only `ubsan` build during debuggin dashpay#6508
and depends only on code revision.
@knst knst force-pushed the fix-no-legacy-bls-secret branch from 291aff7 to f76f943 Compare December 27, 2024 11:06
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: 0

🧹 Nitpick comments (3)
src/rpc/evo.cpp (1)

200-208: LGTM with a suggestion to enhance the comment

The simplification of ParseBLSSecretKey is good, and the comment about modOrder is helpful. Consider expanding the comment to explain why modOrder is always set to false.

-    // Actually, bool flag for bls::PrivateKey has other meaning (modOrder)
+    // The bool flag for bls::PrivateKey controls modOrder behavior.
+    // We always set it to false because <explain rationale here>
src/bls/bls_ies.h (1)

11-15: Documentation looks good, consider adding version information.

The documentation clearly states the assumptions about the basic scheme and serialization approach. Consider adding information about when this assumption was introduced (e.g., which network version) to help with future maintenance.

src/bls/bls_ies.cpp (1)

Line range hint 1-108: Cryptographic implementation follows best practices.

The implementation uses standard cryptographic primitives and techniques:

  • AES256-CBC for encryption
  • Proper IV generation through hash chaining
  • Standard DH key exchange for key derivation

Consider adding a comment documenting the cryptographic design choices and security properties.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 291aff7 and f76f943.

📒 Files selected for processing (26)
  • src/bench/bls.cpp (3 hunks)
  • src/bls/bls.cpp (0 hunks)
  • src/bls/bls.h (3 hunks)
  • src/bls/bls_ies.cpp (4 hunks)
  • src/bls/bls_ies.h (1 hunks)
  • src/bls/bls_worker.cpp (1 hunks)
  • src/coinjoin/coinjoin.cpp (2 hunks)
  • src/evo/assetlocktx.h (1 hunks)
  • src/evo/mnauth.cpp (3 hunks)
  • src/evo/specialtxman.cpp (2 hunks)
  • src/llmq/dkgsession.cpp (5 hunks)
  • src/llmq/dkgsession.h (1 hunks)
  • src/llmq/dkgsessionmgr.cpp (1 hunks)
  • src/llmq/dkgsessionmgr.h (1 hunks)
  • src/llmq/signing_shares.cpp (1 hunks)
  • src/masternode/node.cpp (0 hunks)
  • src/masternode/node.h (0 hunks)
  • src/rpc/evo.cpp (13 hunks)
  • src/rpc/governance.cpp (1 hunks)
  • src/test/bls_tests.cpp (10 hunks)
  • src/test/evo_deterministicmns_tests.cpp (2 hunks)
  • src/test/evo_mnhf_tests.cpp (1 hunks)
  • src/test/rpc_tests.cpp (3 hunks)
  • src/validation.cpp (1 hunks)
  • test/functional/feature_dip3_deterministicmns.py (6 hunks)
  • test/functional/test_framework/test_framework.py (4 hunks)
💤 Files with no reviewable changes (3)
  • src/bls/bls.cpp
  • src/masternode/node.h
  • src/masternode/node.cpp
🚧 Files skipped from review as they are similar to previous changes (17)
  • src/evo/assetlocktx.h
  • src/test/evo_mnhf_tests.cpp
  • src/test/rpc_tests.cpp
  • src/test/evo_deterministicmns_tests.cpp
  • src/llmq/dkgsession.h
  • src/evo/specialtxman.cpp
  • src/llmq/dkgsessionmgr.h
  • src/rpc/governance.cpp
  • src/llmq/signing_shares.cpp
  • src/validation.cpp
  • src/coinjoin/coinjoin.cpp
  • test/functional/test_framework/test_framework.py
  • src/bls/bls_worker.cpp
  • src/bench/bls.cpp
  • src/bls/bls.h
  • src/evo/mnauth.cpp
  • src/test/bls_tests.cpp
🔇 Additional comments (17)
test/functional/feature_dip3_deterministicmns.py (4)

15-15: LGTM: Clean import addition

The addition of softfork_active import is appropriate for the new conditional logic.


229-229: LGTM: Clean conditional BLS key generation

The conditional logic for BLS key generation appropriately handles both legacy and new schemes based on v19 activation status.


257-257: LGTM: Consistent ProTx registration handling

The conditional logic for ProTx registration commands maintains consistency with the BLS scheme changes and properly handles both legacy and new cases.

Also applies to: 273-273


214-214: LGTM: Consistent registrar update handling

The conditional logic for registrar updates follows the same clean pattern used throughout the file and properly handles both legacy and new cases.

Also applies to: 291-291

src/rpc/evo.cpp (3)

310-317: LGTM: Clean implementation of BLS scheme selection

The template-based implementation with explicit legacy scheme control is well-designed and maintainable.


1704-1729: LGTM: Well-documented BLS generate command

The changes to the bls generate command are well-implemented with clear documentation and proper handling of both legacy and new schemes.


1736-1764: LGTM: Consistent BLS fromsecret implementation

The changes to the bls fromsecret command maintain consistency with the bls generate command and provide clear documentation.

src/llmq/dkgsessionmgr.cpp (1)

11-11: LGTM!

The BLS IES header inclusion is properly placed and necessary for the encrypted contributions functionality.

src/llmq/dkgsession.cpp (6)

87-88: LGTM!

The initialization of m_use_legacy_bls correctly determines the BLS scheme based on V19 deployment status.


219-219: LGTM!

The signature generation correctly uses the instance-specific m_use_legacy_bls flag, aligning with the deglobalization effort.


531-531: LGTM!

The complaint signature generation consistently uses the instance-specific BLS scheme flag.


725-725: LGTM!

The justification signature generation maintains consistency by using the instance-specific BLS scheme flag.


Line range hint 87-1025: Excellent consistency in BLS scheme deglobalization

The changes systematically replace the global BLS scheme flag with the instance-specific m_use_legacy_bls across all signature operations in the DKG session. This consistent implementation aligns perfectly with the PR's deglobalization objectives.


1015-1025: LGTM with a note about error simulation

The code consistently uses the instance-specific BLS scheme flag for both signature generation and byte vector operations. The signature manipulation is intentional for testing error scenarios.

✅ Verification successful

Error simulation is part of DKG testing framework

The code is part of a Distributed Key Generation (DKG) testing framework where ShouldSimulateError is used to deliberately inject various types of errors (CONTRIBUTION_OMIT, CONTRIBUTION_LIE, COMPLAIN_LIE, JUSTIFY_LIE, COMMIT_OMIT, COMMIT_LIE) for testing the robustness of the DKG protocol. The signature manipulation in the reviewed code is specifically for testing error scenarios in the commitment phase and is controlled by the DKG error simulation framework.

  • src/llmq/dkgsession.h: Defines the error simulation interface
  • src/llmq/dkgsession.cpp: Implements various error scenarios including contribution lies, justification lies, and commitment lies
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Verify that error simulation is only used in test code
rg "ShouldSimulateError.*COMMIT_LIE" --type cpp

Length of output: 132


Script:

#!/bin/bash
# Check if this is in test code by looking for test-related indicators
rg "ShouldSimulateError.*COMMIT_LIE" -B 10 -A 10

# Also check for test-related includes or definitions
rg "ShouldSimulateError" --type cpp -B 5

Length of output: 4554

src/bls/bls_ies.h (1)

Line range hint 1-120: Verify encryption path coverage after method removals.

The removal of multiple Encrypt methods simplifies the API, but we should verify that all encryption use cases are still properly covered by the remaining implementation.

Let's verify the usage patterns:

✅ Verification successful

Let me gather more information about the BLS IES encryption usage and tests.


Let me check the actual usage of the BLS IES encryption in the codebase to understand the encryption patterns.


Let me check the LLMQ directory specifically since the previous command had an issue.


Based on the gathered information, I can now provide the final response:

BLS IES encryption changes maintain all required functionality

The removal of Encrypt methods from the BLS IES implementation is safe as the essential encryption paths are still properly covered:

  1. The core encryption functionality is maintained through CBLSIESMultiRecipientBlobs::Encrypt which is actively used in:

    • DKG session management for LLMQ (Quorum) member contributions
    • Masternode operations for secure key exchange
  2. The remaining implementation supports all current use cases:

    • Multi-recipient encryption for DKG contributions (used in src/llmq/dkgsession.cpp)
    • Encrypted object handling in quorum formation (src/llmq/quorums.cpp)
    • Secure masternode communications (src/masternode/node.cpp)

The removed methods were likely redundant implementations, and the current encryption paths through CBLSIESMultiRecipientBlobs and CBLSIESEncryptedObject templates provide a more focused and maintainable API while preserving all necessary security features.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for all encryption method calls in the codebase
echo "Searching for encryption method calls..."
rg "Encrypt\(" --type cpp

# Search for potential encryption-related tests
echo "Searching for related test files..."
fd -e cpp -e h "test.*bls.*ies"

Length of output: 8402


Script:

#!/bin/bash
# Search for BLS IES test files and their content
echo "Searching for BLS IES tests..."
rg -l "CBLSIESMultiRecipientBlobs|CBLSIESEncryptedObject" --type cpp

echo -e "\nChecking test content..."
rg "TEST.*bls.*ies" --type cpp -B 2 -A 2

echo -e "\nChecking for removed Encrypt methods in git history..."
git log -p --no-merges -- src/bls/bls_ies.h src/bls/bls_ies.cpp | rg "^[-+].*Encrypt.*\("

Length of output: 509


Script:

#!/bin/bash
# Check how BLS IES encryption is used in the codebase
echo "Checking BLS IES usage in masternode..."
rg -A 5 -B 5 "CBLSIESMultiRecipientBlobs|CBLSIESEncryptedObject" src/masternode/node.cpp

echo -e "\nChecking BLS IES usage in LLMQ..."
rg -A 5 -B 5 "CBLSIESMultiRecipientBlobs|CBLSIESEncryptedObject" "src/llmq/*.cpp"

echo -e "\nChecking current implementation of encryption methods..."
rg "bool.*Encrypt" src/bls/bls_ies.cpp

Length of output: 1676


Script:

#!/bin/bash
# Check LLMQ usage with correct path
echo "Checking BLS IES usage in LLMQ..."
rg -A 5 -B 5 "CBLSIESMultiRecipientBlobs|CBLSIESEncryptedObject" src/llmq/

echo -e "\nChecking DKG session implementation..."
rg -A 10 "contributions->InitEncrypt|contributions->Encrypt" src/llmq/dkgsession.cpp

echo -e "\nChecking for any encryption-related tests..."
fd -e cpp "test" | xargs rg "CBLSIESMultiRecipientBlobs|CBLSIESEncryptedObject"

Length of output: 5705

src/bls/bls_ies.cpp (2)

Line range hint 12-19: Good simplification of the EncryptBlob interface.

Removing the template parameter in favor of a concrete type improves type safety and makes the interface more explicit.


47-47: Verify implications of explicit basic scheme usage in key derivation.

The change to use ToByteVector(false) explicitly specifies the basic scheme for key derivation. This is a security-critical change that affects the symmetric key generation process.

Let's verify the consistency of this change:

Also applies to: 83-83, 100-100

✅ Verification successful

Let me generate another script to search for more specific information about the key derivation usage.


Let me search for more context about the BLS scheme usage.


Based on the gathered information, I can now provide the final response:

Explicit basic scheme usage in key derivation is correct and intentional

The explicit ToByteVector(false) usage in BLS IES key derivation is correct and consistent with the module's design. From the code comments in src/bls/bls_ies.h, this module explicitly works under the assumption that the basic scheme is available on all masternodes, and serialization of public keys for Encrypt and Decrypt operations is intentionally done using the Basic Scheme.

Key findings:

  • The module's documentation explicitly states this requirement: "All objects in this module working from assumption that basic scheme is available on all masternodes"
  • The implementation consistently uses ToByteVector(false) for symmetric key derivation across all encryption/decryption operations
  • The symmetric key is properly derived and resized to 32 bytes after extraction
  • This approach ensures consistent key derivation behavior independent of the global BLS scheme setting (bls_legacy_scheme)
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for all ToByteVector calls to ensure consistent usage
echo "Checking ToByteVector usage patterns..."
rg "ToByteVector\(" --type cpp -A 1 -B 1

# Search for any tests verifying key derivation
echo "Searching for key derivation tests..."
rg "DHKeyExchange.*ToByteVector" --type cpp

Length of output: 65894


Script:

#!/bin/bash
# Search for key derivation related code in bls_ies.cpp
echo "Checking key derivation in bls_ies.cpp..."
rg "symKey|ToByteVector" src/bls/bls_ies.cpp -B 2 -A 2

# Search for tests related to BLS IES encryption
echo "Checking BLS IES tests..."
rg "bls_ies.*test" -l

Length of output: 1777


Script:

#!/bin/bash
# Search for BLS scheme related code and tests
echo "Checking BLS scheme usage..."
rg "legacy.*scheme|basic.*scheme" src/bls/ -B 2 -A 2

# Search for BLS ToByteVector implementations
echo "Checking BLS ToByteVector implementations..."
ast-grep --pattern 'ToByteVector($_, $_) { $$$ }'

Length of output: 4451

@knst knst requested a review from UdjinM6 December 27, 2024 19:02
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