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

feat:add chacha20 cipher + z85 encoding #50

Merged
merged 12 commits into from
Jan 3, 2025
Merged

feat:add chacha20 cipher + z85 encoding #50

merged 12 commits into from
Jan 3, 2025

Conversation

JarbasAl
Copy link
Member

@JarbasAl JarbasAl commented Jan 2, 2025

configurable ciphers for encryption, reports available ones during handshake

adds ChaCha20 as an option

allows specifying b64/hex encoding during handshake

Summary by CodeRabbit

  • New Features

    • Enhanced encryption capabilities with configurable cipher options for JSON and binary data.
    • Added support for multiple encryption schemes (AES-GCM-128, ChaCha20-Poly1305).
    • Introduced new exception classes for unsupported ciphers, invalid encodings, and invalid key sizes.
    • Updated command for key management to reflect changes in key type.
    • Added a method to determine optimal cipher types based on CPU capabilities.
    • Implemented a new Z85b encoding class for improved data encoding.
  • Bug Fixes

    • Improved error handling for encryption and decryption processes.
  • Documentation

    • Added deprecation warnings for legacy encryption functions.
  • Refactor

    • Restructured encryption and protocol handling to support more flexible message security.
    • Streamlined handshake process with enhanced cipher negotiation.
    • Updated function signatures to improve clarity and usability.
  • Chores

    • Added new dependencies to the requirements file.

configurable ciphers for encryption, reports available ones during handshake

adds ChaCha20 as an option

allows specifying b64/hex encoding during handshake
Copy link
Contributor

coderabbitai bot commented Jan 2, 2025

Warning

Rate limit exceeded

@JarbasAl has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 8 minutes and 18 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.

📥 Commits

Reviewing files that changed from the base of the PR and between e93b1a3 and c8cbc26.

📒 Files selected for processing (2)
  • hivemind_bus_client/encryption.py (1 hunks)
  • hivemind_bus_client/message.py (1 hunks)

Walkthrough

This pull request introduces significant enhancements to the HiveMind Bus Client library's encryption capabilities. A new encryption module is created, defining multiple cipher types for JSON and binary data. The HiveMessageBusClient class is updated to support these new cipher options, allowing for more flexible message encryption and decryption. Additionally, the protocol and utility modules are modified to accommodate these changes, improving the overall security and configurability of the message handling processes.

Changes

File Change Summary
hivemind_bus_client/client.py Added new cipher parameters json_cipher and bin_cipher to HiveMessageBusClient constructor; updated on_message and emit methods to include cipher arguments.
hivemind_bus_client/encryption.py New module with comprehensive encryption functions; added SupportedEncodings and SupportedCiphers enums; implemented methods for encrypting/decrypting JSON and binary data; added CPU support check.
hivemind_bus_client/exceptions.py Added new InvalidCipher, InvalidEncoding, and InvalidKeySize exceptions for handling unsupported encryption schemes and key size errors.
hivemind_bus_client/protocol.py Updated HiveMindSlaveProtocol to include optimal ciphers; refactored start_handshake and handle_handshake methods to process new cipher payloads.
hivemind_bus_client/util.py Deprecated existing encryption functions; updated decompress_payload to accept only bytes; removed pybase64 import.
hivemind_bus_client/scripts.py Updated reset-pgp command help text and renamed function from reset_pgp_key to reset_keys.
requirements.txt Added pybase64 and py-cpuinfo as new dependencies.
hivemind_bus_client/z85b.py Introduced new Z85b encoding implementation with encoding and decoding methods; added Z85DecodeError for handling decoding errors.

Possibly related PRs

  • fix: dont leak session data / implement client HELLO #48: The changes in hivemind_bus_client/protocol.py related to the start_handshake method and the handling of encryption and ciphers during the handshake process are relevant to the main PR's focus on enhancing encryption capabilities in the HiveMessageBusClient class.

🐰 In the land of code where rabbits hop,
New ciphers dance, and old ones stop.
With encryptions strong and keys so bright,
We celebrate changes that feel just right!
Hooray for the updates, let’s give a cheer,
For secure messages, we hold so dear! 🎉


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.

@github-actions github-actions bot added feature and removed feature labels Jan 2, 2025
Copy link
Contributor

@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: 2

🧹 Nitpick comments (9)
hivemind_bus_client/util.py (2)

136-146: Well-handled deprecation notice.

The re-routing to the new encryption module using encrypt_as_json helps maintain backward compatibility while guiding users to the updated API. Consider adding a target version or date for removal to further clarify timelines.


176-185: Consistent usage of BinaryCiphers.

The deprecation warning clarifies the migration path to the new encryption module. Watch for potential collisions if other cipher modes are added in the future.

hivemind_bus_client/encryption.py (6)

45-86: Flexible JSON encryption with fallback on AES or ChaCha.

The approach to select the cipher type (AES or ChaCha20) and encoding format (Base64 or Hex) in a single function makes the API straightforward. Consider enumerating expected key lengths for AES vs. ChaCha20 to provide early validation.


88-128: Robust JSON decryption logic.

The attempt to decode using one encoding and fallback to another is user-friendly. However, overly broad tries can mask potential misconfigurations. Consider logging or communicating which attempt succeeds for easier debugging.


130-156: Binary encryption function is straightforward.

Raising EncryptionKeyError ensures consistent error handling. The function is well-structured, though adding a note on expected key length (16 vs 32 bytes) can prevent confusion when switching between AES-GCM-128 and ChaCha20.


158-185: Binary decryption with support for multiple ciphers.

Similarly to the encryption counterpart, consider adding an optional check for key length or nonce length to further reduce runtime issues.


233-257: ChaCha20 encryption with enforced key/nonce sizes.

Well done verifying the key is 32 bytes and the nonce is 12 bytes. Update the docstring line 237 to reflect that it encrypts with ChaCha20-Poly1305, not AES-GCM-128.

-    Encrypts plaintext using AES-GCM-128.
+    Encrypts plaintext using ChaCha20-Poly1305.

259-286: ChaCha20 decryption.

The same note applies to the docstring line 264. The rest looks consistent with the encryption logic.

-    Decrypts ciphertext encrypted using AES-GCM-128.
+    Decrypts ciphertext encrypted using ChaCha20-Poly1305.
hivemind_bus_client/protocol.py (1)

147-155: Handshake payload includes available cipher lists.

Exposing all supported ciphers helps in negotiating supported algorithms. However, including the entire list might lead to large handshake messages. If the list grows, consider a dynamic approach to reduce overhead, e.g., a short list of user-enabled ciphers.

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between a15d7a2 and 1a03937.

📒 Files selected for processing (5)
  • hivemind_bus_client/client.py (5 hunks)
  • hivemind_bus_client/encryption.py (1 hunks)
  • hivemind_bus_client/exceptions.py (1 hunks)
  • hivemind_bus_client/protocol.py (2 hunks)
  • hivemind_bus_client/util.py (2 hunks)
🧰 Additional context used
🪛 Ruff (0.8.2)
hivemind_bus_client/client.py

105-105: Do not perform function call BinaryDataCallbacks in argument defaults; instead, perform the call within the function, or read the default from a module-level singleton variable

(B008)

hivemind_bus_client/util.py

161-161: Do not use bare except

(E722)


162-162: Within an except clause, raise exceptions with raise ... from err or raise ... from None to distinguish them from errors in exception handling

(B904)

hivemind_bus_client/encryption.py

291-291: Yoda condition detected

(SIM300)

🔇 Additional comments (16)
hivemind_bus_client/util.py (3)

109-109: Good simplification of the signature.

Changing decompress_payload to accept only bytes clarifies the API and eliminates confusion about whether data should be in string or byte form. Ensure this update doesn't break call sites that previously passed a string input.


131-135: Deprecation approach is consistent.

It's good to see a clear marker for deprecated code, including warnings. This ensures library users have ample notice to migrate to the new encryption functions.


165-174: AES-based encryption stubs are fine.

This deprecated function adequately warns users. Ensure tests cover both the new and old encryption paths for a smooth migration.

hivemind_bus_client/encryption.py (6)

12-20: Clear cipher naming conventions.

The JsonCiphers enum has descriptive names. Consider verifying that each cipher is thoroughly tested to avoid surprises in production.


22-33: Documentation of ciphers is helpful.

Providing references (RFC links) is excellent for maintainers. The enumerations for binary encryption appear consistent with standard cryptographic practices.


35-43: Text-based cipher coverage is beneficial.

Adding separate enums for JSON vs. pure text ciphers is a solid approach, giving developers specialized control over the format.


187-209: AES-GCM encryption block.

The usage of cipher.nonce is correct for dynamic nonce generation. For reliability, add tests ensuring truncated or longer keys are handled gracefully.


211-231: AES-GCM decryption block.

This is a clean, standard approach to AES decryption with tag verification. Good choice raising ValueError for failures. Make sure to log or handle decrypt failures gracefully upstream.


288-298: Demo code effectively tests the new ciphers.

Testing encrypt_ChaCha20_Poly1305 and verifying with decrypt_ChaCha20_Poly1305 is a nice demonstration. It ensures that the code is exercised in a self-contained manner.

🧰 Tools
🪛 Ruff (0.8.2)

291-291: Yoda condition detected

(SIM300)

hivemind_bus_client/protocol.py (1)

12-12: Encryption imports

Bringing in JsonCiphers and BinaryCiphers is aligned with other modules. Make sure that all references to these ciphers are covered by unit tests for handshake scenarios.

hivemind_bus_client/client.py (5)

4-4: Literal import is correct for typed parameters.

This expands clarity on allowable cipher types.


20-21: Centralizing serialization and encryption imports.

Organizing these imports together with the newly introduced ciphers is consistent. Double-check that no circular dependencies arise from referencing util and encryption in the same file.


110-111: Cipher parameters integrated neatly.

It’s a clear approach to store both json_cipher and bin_cipher directly on the client. This ensures intuitive usage in the emission and receiving logic.


279-279: Consistent usage of binary vs JSON decryption.

Decrypting data based on the message type (bytes vs. JSON) is a clear separation of concerns. Confirm that the fallback logic handles incorrectly typed payloads gracefully.

Also applies to: 283-283


375-375: Encryption aligns with user-selected cipher.

These lines show good consistency with the new cipher approach using encrypt_bin or encrypt_as_json. Double-check that upstream code sets the appropriate json_cipher and bin_cipher before calling emit.

Also applies to: 382-382

hivemind_bus_client/exceptions.py (1)

14-16: Fit-for-purpose InvalidCipher exception.

This exception is specific and clarifies errors when an unsupported cipher is used. This ensures better debugging over a generic exception.

hivemind_bus_client/util.py Outdated Show resolved Hide resolved
hivemind_bus_client/client.py Outdated Show resolved Hide resolved
@github-actions github-actions bot added feature and removed feature labels Jan 2, 2025
Copy link
Contributor

@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 (8)
hivemind_bus_client/scripts.py (1)

201-202: Use a more descriptive command name or docstring.
While "reset-pgp" is still referenced in the command name, the docstring refers to recreating an RSA key, moving away from PGP terminology. Consider renaming either the command or the help text to avoid confusion.

hivemind_bus_client/encryption.py (5)

50-51: Validate default JSON cipher usage.
JSON_B64_AES_GCM_128 is set as the default, but ensure this is explicitly documented in external docs or function docstrings to help users understand the default behavior.


68-69: Consistent error handling for ciphers.
Good job raising InvalidCipher early. Consider adding a hint about valid cipher names in the exception message to aid debugging.


84-90: Consider uniform naming for encoded data fields.
"ciphertext," "tag," and "nonce" are used in the JSON structure. If you anticipate more fields (e.g., salt, key-derivation info), establish a consistent naming pattern or an envelope property.


127-133: Add supportive logging for decryption failures.
Currently, a generic DecryptionKeyError is raised. Consider adding optional debug logs (like ciphertext length, cipher used, etc.) to expedite troubleshooting, while remaining mindful about leaking sensitive info.


296-296: Address Yoda condition (static analysis).
You can reverse the comparison for better readability:

-print("JSON-B64-AES-GCM-128" == JsonCiphers.JSON_B64_AES_GCM_128)
+print(JsonCiphers.JSON_B64_AES_GCM_128 == "JSON-B64-AES-GCM-128")
🧰 Tools
🪛 Ruff (0.8.2)

296-296: Yoda condition detected

(SIM300)

hivemind_bus_client/protocol.py (2)

3-3: Avoid wildcard use in type hints if not needed.
If Tuple is needed exclusively for (JsonCiphers, BinaryCiphers), consider a direct from typing import Tuple with specific usage to keep code simpler.


197-199: User feedback on final cipher choice.
Logging the chosen cipher is great. Consider also sending an acknowledgment message (if relevant) back to the client about which ciphers are in use, in case the handshake occurs in a headless environment.

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 1a03937 and 876b0ce.

📒 Files selected for processing (5)
  • hivemind_bus_client/client.py (4 hunks)
  • hivemind_bus_client/encryption.py (1 hunks)
  • hivemind_bus_client/protocol.py (5 hunks)
  • hivemind_bus_client/scripts.py (1 hunks)
  • requirements.txt (1 hunks)
🧰 Additional context used
🪛 Ruff (0.8.2)
hivemind_bus_client/encryption.py

296-296: Yoda condition detected

(SIM300)

🔇 Additional comments (10)
requirements.txt (1)

7-8: Confirm necessity of new dependencies.
Make sure these new libraries are essential. If not, it might complicate the environment for downstream users.

✅ Verification successful

Let me check the usage of py-cpuinfo since we only found references to pybase64.


Let me check how cpuinfo is being used in the encryption module to understand its necessity.


Both dependencies serve essential purposes in the codebase

  • pybase64 is extensively used in the protocol, encryption, and client modules for encoding/decoding messages and cryptographic data
  • py-cpuinfo is used to detect CPU AES instruction support, which is crucial for optimal encryption performance by determining hardware capabilities
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Checking references to pybase64 and py-cpuinfo in the code to confirm usage
rg 'pybase64|py-cpuinfo'

Length of output: 1042


Script:

#!/bin/bash
# Search for py-cpuinfo usage with context
rg -A 3 'cpuinfo'

Length of output: 316


Script:

#!/bin/bash
# Get context around cpuinfo usage in encryption.py
rg -B 5 -A 10 'from cpuinfo import'

Length of output: 1004

hivemind_bus_client/encryption.py (3)

13-15: Clarify CPU detection approach.
cpu_supports_AES() relies on CPU flags that might vary across environments. Consider fallback logic or user notification if AES is not supported.


151-152: Maintain uniform error patterns.
Just like above for JSON ciphers, raising InvalidCipher quickly is a good pattern. Well done.


194-206: 🛠️ Refactor suggestion

Confirm docstring alignment.
The docstrings for encrypt_ChaCha20_Poly1305 and decrypt_ChaCha20_Poly1305 mention AES-GCM-128 in their headings. Update them to mention ChaCha20-Poly1305 for clarity.

-"""Encrypts plaintext using AES-GCM-128."""
+"""Encrypts plaintext using ChaCha20-Poly1305."""

Likely invalid or redundant comment.

hivemind_bus_client/protocol.py (3)

122-131: Solid approach for CPU-based cipher selection.
This property method provides a clean, centralized mechanism for choosing the best cipher set. Good job keeping it short and clear.


157-165: Clarify cipher list usage in handshake.
You're sending json_ciphers and binary_ciphers as lists. If the recipient doesn't handle them properly, it might lead to confusion. Document the expected behavior for remote handshake logic.


12-12: Verify consistent usage across the codebase.
cpu_supports_AES, JsonCiphers, BinaryCiphers come from encryption.py. Confirm that any other references in client.py or util.py (if they exist) also import from the same place to avoid duplication.

✅ Verification successful

All imports and usages of encryption components are consistent

The verification shows that all references to cpu_supports_AES, JsonCiphers, and BinaryCiphers are properly imported from hivemind_bus_client.encryption. The usage is consistent across the codebase:

  • protocol.py imports and uses them for cipher selection logic
  • client.py imports JsonCiphers and BinaryCiphers for default cipher configuration
  • util.py imports JsonCiphers and BinaryCiphers for encryption/decryption utility functions
  • All implementations are defined in encryption.py
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
rg 'cpu_supports_AES|JsonCiphers|BinaryCiphers'

Length of output: 5287

hivemind_bus_client/client.py (3)

21-21: LGTM: Clean import of encryption-related functions and types.

The import statement is well-organized and includes all necessary encryption components.


276-276: LGTM: Proper use of configured ciphers for decryption.

The decryption calls correctly use the configured ciphers and maintain existing error handling.

Also applies to: 280-280


372-372: LGTM: Proper use of configured ciphers for encryption.

The encryption calls correctly use the configured ciphers based on message type. However, let's verify that all encryption-related code paths are properly tested.

Also applies to: 379-379

hivemind_bus_client/client.py Outdated Show resolved Hide resolved
@github-actions github-actions bot added feature and removed feature labels Jan 2, 2025
Copy link
Contributor

@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: 5

🧹 Nitpick comments (4)
hivemind_bus_client/encryption.py (4)

13-14: Consider caching the CPU feature detection result

The cpu_supports_AES() function calls get_cpu_info() on every invocation, which is unnecessary as CPU features don't change during runtime.

Consider caching the result:

+_cpu_aes_support = None
+
 def cpu_supports_AES() -> bool:
-    return "aes" in get_cpu_info()["flags"]
+    global _cpu_aes_support
+    if _cpu_aes_support is None:
+        _cpu_aes_support = "aes" in get_cpu_info()["flags"]
+    return _cpu_aes_support

17-38: Enhance enum documentation with key size requirements

The enums are well-documented with specification references, but should also document key size requirements for each cipher.

Add key size information to the docstrings:

  • AES-GCM-128 requires a 16-byte key
  • ChaCha20-Poly1305 requires a 32-byte key

286-286: Simplify comparison by removing Yoda condition

Yoda conditions are unnecessary in Python as assignment in conditions is not allowed.

-    print("JSON-B64-AES-GCM-128" == JsonCiphers.JSON_B64_AES_GCM_128)
+    print(JsonCiphers.JSON_B64_AES_GCM_128 == "JSON-B64-AES-GCM-128")
🧰 Tools
🪛 Ruff (0.8.2)

286-286: Yoda condition detected

(SIM300)


283-293: Enhance test coverage

The test section only covers ChaCha20 encryption with binary data.

Consider adding tests for:

  • AES-GCM-128 encryption/decryption
  • JSON format encryption/decryption
  • Error cases (invalid key sizes, decryption failures)

Would you like me to generate comprehensive test cases for all these scenarios?

🧰 Tools
🪛 Ruff (0.8.2)

286-286: Yoda condition detected

(SIM300)

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 876b0ce and 4481a08.

📒 Files selected for processing (1)
  • hivemind_bus_client/encryption.py (1 hunks)
🧰 Additional context used
🪛 Ruff (0.8.2)
hivemind_bus_client/encryption.py

286-286: Yoda condition detected

(SIM300)

hivemind_bus_client/encryption.py Outdated Show resolved Hide resolved
hivemind_bus_client/encryption.py Outdated Show resolved Hide resolved
hivemind_bus_client/encryption.py Outdated Show resolved Hide resolved
hivemind_bus_client/encryption.py Outdated Show resolved Hide resolved
hivemind_bus_client/encryption.py Outdated Show resolved Hide resolved
@github-actions github-actions bot added feature and removed feature labels Jan 2, 2025
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Copy link
Contributor

@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

♻️ Duplicate comments (5)
hivemind_bus_client/encryption.py (5)

71-75: 🛠️ Refactor suggestion

Replace hardcoded sizes with cipher-specific constants.

The hardcoded sizes for nonce and tag should be replaced with named constants for better maintainability and clarity.

As mentioned in a previous review, define and use cipher-specific constants:

+# Cipher-specific constants
+AES_GCM_NONCE_SIZE = 16
+AES_GCM_TAG_SIZE = 16
+CHACHA20_NONCE_SIZE = 12
+CHACHA20_TAG_SIZE = 16

-    if cipher in aes_ciphers:
-        nonce, ciphertext, tag = ciphertext[:16], ciphertext[16:-16], ciphertext[-16:]
-    else:
-        nonce, ciphertext, tag = ciphertext[:12], ciphertext[12:-16], ciphertext[-16:]
+    nonce_size = AES_GCM_NONCE_SIZE if cipher in aes_ciphers else CHACHA20_NONCE_SIZE
+    tag_size = AES_GCM_TAG_SIZE if cipher in aes_ciphers else CHACHA20_TAG_SIZE
+    nonce, ciphertext, tag = ciphertext[:nonce_size], ciphertext[nonce_size:-tag_size], ciphertext[-tag_size:]

134-134: 🛠️ Refactor suggestion

Update documentation to include ChaCha20-Poly1305 support.

The documentation incorrectly states that only BINARY_AES_GCM_128 is supported.

Update the documentation to include both supported ciphers:

-        cipher (BinaryCiphers): The encryption cipher. Only BINARY_AES_GCM_128 is supported.
+        cipher (BinaryCiphers): The encryption cipher. Supported options:
+            - BINARY_AES_GCM_128: AES-GCM with 128-bit key
+            - BINARY_CHACHA20_POLY1305: ChaCha20-Poly1305 with 256-bit key

174-179: 🛠️ Refactor suggestion

Replace hardcoded sizes with cipher-specific constants.

Similar to the JSON functions, replace hardcoded sizes with named constants.

Use the same constants defined earlier:

-    if cipher == BinaryCiphers.BINARY_AES_GCM_128:
-        nonce, ciphertext, tag = ciphertext[:16], ciphertext[16:-16], ciphertext[-16:]
-    else:
-        nonce, ciphertext, tag = ciphertext[:12], ciphertext[12:-16], ciphertext[-16:]
+    nonce_size = AES_GCM_NONCE_SIZE if cipher == BinaryCiphers.BINARY_AES_GCM_128 else CHACHA20_NONCE_SIZE
+    tag_size = AES_GCM_TAG_SIZE if cipher == BinaryCiphers.BINARY_AES_GCM_128 else CHACHA20_TAG_SIZE
+    nonce, ciphertext, tag = ciphertext[:nonce_size], ciphertext[nonce_size:-tag_size], ciphertext[-tag_size:]

189-208: 🛠️ Refactor suggestion

Add key size validation for AES-GCM-128.

ChaCha20 implementation validates key size but AES-GCM-128 doesn't.

Add key size validation:

 def encrypt_AES_GCM_128(key: Union[str, bytes], text: Union[str, bytes],
                         nonce: Optional[bytes] = None) -> tuple[bytes, bytes, bytes]:
     if not isinstance(text, bytes):
         text = bytes(text, encoding="utf-8")
     if not isinstance(key, bytes):
         key = bytes(key, encoding="utf-8")
+    if len(key) != 16:  # AES-128 uses 128 bit/16 byte keys
+        raise ValueError("AES-GCM-128 requires a 16-byte key")
     cipher = AES.new(key, AES.MODE_GCM, nonce=nonce)

237-237: 🛠️ Refactor suggestion

Fix incorrect docstring in ChaCha20_Poly1305 encryption.

The docstring incorrectly states it uses AES-GCM-128 instead of ChaCha20-Poly1305.

-    Encrypts plaintext using AES-GCM-128.
+    Encrypts plaintext using ChaCha20-Poly1305.
🧹 Nitpick comments (1)
hivemind_bus_client/encryption.py (1)

291-291: Avoid Yoda conditions for better readability.

The comparison uses a Yoda condition which is less readable.

-    print("JSON-B64-AES-GCM-128" == JsonCiphers.JSON_B64_AES_GCM_128)
+    print(JsonCiphers.JSON_B64_AES_GCM_128 == "JSON-B64-AES-GCM-128")
🧰 Tools
🪛 Ruff (0.8.2)

291-291: Yoda condition detected

(SIM300)

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 4481a08 and 03d0699.

📒 Files selected for processing (1)
  • hivemind_bus_client/encryption.py (1 hunks)
🧰 Additional context used
🪛 Ruff (0.8.2)
hivemind_bus_client/encryption.py

291-291: Yoda condition detected

(SIM300)

🔇 Additional comments (2)
hivemind_bus_client/encryption.py (2)

1-15: LGTM! Well-organized imports and CPU detection.

The imports are logically grouped, and the CPU detection function is focused and straightforward.


17-38: LGTM! Well-documented cipher enums with specification links.

The enums are clearly named and well-documented. The inclusion of specification links in BinaryCiphers is particularly helpful for future reference.

@github-actions github-actions bot added feature and removed feature labels Jan 2, 2025
Copy link
Contributor

@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

♻️ Duplicate comments (1)
hivemind_bus_client/encryption.py (1)

71-75: 🛠️ Refactor suggestion

Replace hardcoded cipher-specific sizes with constants

The hardcoded sizes for nonce and tag should be replaced with named constants to improve maintainability and reduce the risk of errors:

+# Cipher-specific constants
+AES_NONCE_SIZE = 16
+CHACHA20_NONCE_SIZE = 12
+TAG_SIZE = 16

-    nonce, ciphertext, tag = ciphertext[:16], ciphertext[16:-16], ciphertext[-16:]
+    nonce_size = AES_NONCE_SIZE if cipher in aes_ciphers else CHACHA20_NONCE_SIZE
+    nonce, ciphertext, tag = ciphertext[:nonce_size], ciphertext[nonce_size:-TAG_SIZE], ciphertext[-TAG_SIZE:]
🧹 Nitpick comments (3)
hivemind_bus_client/encryption.py (3)

17-38: Enhance cipher documentation with key size requirements

The enum documentation would benefit from explicitly stating the key size requirements for each cipher:

  • AES-GCM-128: 16 bytes (128 bits)
  • ChaCha20-Poly1305: 32 bytes (256 bits)

This would make it clearer for users implementing key management.


292-302: Move test code to a dedicated test file

The test code in the __main__ block should be moved to a proper test file to maintain separation of concerns and enable proper test discovery.

Would you like me to help create a test file with comprehensive test cases?

🧰 Tools
🪛 Ruff (0.8.2)

295-295: Yoda condition detected

(SIM300)


295-295: Fix Yoda condition

Replace the Yoda condition with a more readable standard comparison:

-    print("JSON-B64-AES-GCM-128" == JsonCiphers.JSON_B64_AES_GCM_128)
+    print(JsonCiphers.JSON_B64_AES_GCM_128 == "JSON-B64-AES-GCM-128")
🧰 Tools
🪛 Ruff (0.8.2)

295-295: Yoda condition detected

(SIM300)

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 03d0699 and cbf5061.

📒 Files selected for processing (1)
  • hivemind_bus_client/encryption.py (1 hunks)
🧰 Additional context used
🪛 Ruff (0.8.2)
hivemind_bus_client/encryption.py

295-295: Yoda condition detected

(SIM300)

🔇 Additional comments (3)
hivemind_bus_client/encryption.py (3)

6-8: Consider pinning cryptographic library versions

For security-critical dependencies like pycryptodomex (imported as Cryptodome), consider pinning the version in requirements.txt to prevent potential security regressions from automatic updates.


164-164: ⚠️ Potential issue

Fix incorrect documentation in decrypt_bin

The documentation states that only BINARY_AES_GCM_128 is supported, but the function also supports BINARY_CHACHA20_POLY1305.

-        cipher (BinaryCiphers): The cipher used for encryption. Only BINARY_AES_GCM_128 is supported.
+        cipher (BinaryCiphers): The cipher used for encryption. Supported options:
+            - BINARY_AES_GCM_128: AES-GCM with 128-bit key
+            - BINARY_CHACHA20_POLY1305: ChaCha20-Poly1305 with 256-bit key

Likely invalid or redundant comment.


268-268: ⚠️ Potential issue

Fix incorrect docstring in ChaCha20_Poly1305 decryption

The docstring incorrectly states it decrypts AES-GCM-128 instead of ChaCha20-Poly1305.

-    Decrypts ciphertext encrypted using AES-GCM-128.
+    Decrypts ciphertext encrypted using ChaCha20-Poly1305.

Likely invalid or redundant comment.

hivemind_bus_client/encryption.py Outdated Show resolved Hide resolved
@github-actions github-actions bot added feature and removed feature labels Jan 2, 2025
Copy link
Contributor

@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 (2)
hivemind_bus_client/encryption.py (2)

337-340: Simplify nested if statements.

The nested if statements for nonce validation can be simplified.

Apply this diff:

-    if nonce:
-        if len(nonce) != CHACHA20_NONCE_SIZE:  # 92bits/12bytes per RFC7539
+    if nonce and len(nonce) != CHACHA20_NONCE_SIZE:  # 92bits/12bytes per RFC7539

Same applies to the second occurrence at lines 370-373.

Also applies to: 370-373

🧰 Tools
🪛 Ruff (0.8.2)

337-338: Use a single if statement instead of nested if statements

Combine if statements using and

(SIM102)


377-387: Add comprehensive test cases.

The test cases only cover ChaCha20. Consider adding tests for:

  • AES-GCM and AES-CCM
  • Different key sizes
  • Error cases
  • JSON encoding/decoding

Would you like me to generate additional test cases?

🧰 Tools
🪛 Ruff (0.8.2)

380-380: Yoda condition detected

Rewrite as SupportedEncodings.JSON_B64 == "JSON-B64"

(SIM300)

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between cbf5061 and 9118883.

📒 Files selected for processing (5)
  • hivemind_bus_client/client.py (4 hunks)
  • hivemind_bus_client/encryption.py (1 hunks)
  • hivemind_bus_client/exceptions.py (1 hunks)
  • hivemind_bus_client/protocol.py (5 hunks)
  • hivemind_bus_client/util.py (3 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • hivemind_bus_client/exceptions.py
🧰 Additional context used
🪛 Ruff (0.8.2)
hivemind_bus_client/protocol.py

3-3: typing.Tuple imported but unused

Remove unused import: typing.Tuple

(F401)

hivemind_bus_client/encryption.py

337-338: Use a single if statement instead of nested if statements

Combine if statements using and

(SIM102)


370-371: Use a single if statement instead of nested if statements

Combine if statements using and

(SIM102)


380-380: Yoda condition detected

Rewrite as SupportedEncodings.JSON_B64 == "JSON-B64"

(SIM300)

hivemind_bus_client/util.py

162-162: Do not use bare except

(E722)


163-163: Within an except clause, raise exceptions with raise ... from err or raise ... from None to distinguish them from errors in exception handling

(B904)

🔇 Additional comments (10)
hivemind_bus_client/util.py (3)

110-110: LGTM! Type safety improvement.

The function signature change to only accept bytes improves type safety and makes the interface clearer.


132-186: LGTM! Well-structured deprecation notices.

The deprecation warnings are well implemented with:

  • Clear warning messages directing users to the new module
  • Proper stacklevel setting
  • Graceful forwarding to new implementations
🧰 Tools
🪛 Ruff (0.8.2)

162-162: Do not use bare except

(E722)


163-163: Within an except clause, raise exceptions with raise ... from err or raise ... from None to distinguish them from errors in exception handling

(B904)


161-163: ⚠️ Potential issue

Fix bare except clause.

The bare except clause can mask important errors. Consider catching specific exceptions.

Apply this diff to improve error handling:

-        except:
-            raise e
+        except Exception as sub_e:
+            raise e from sub_e

Likely invalid or redundant comment.

🧰 Tools
🪛 Ruff (0.8.2)

162-162: Do not use bare except

(E722)


163-163: Within an except clause, raise exceptions with raise ... from err or raise ... from None to distinguish them from errors in exception handling

(B904)

hivemind_bus_client/protocol.py (2)

186-191: LGTM! Good logging implementation.

The debug logging of selected cipher and encoding will help with troubleshooting.


146-148: Consider validating cipher compatibility.

The code sends all supported ciphers and encodings without checking if they're actually available on the system.

Consider filtering the cipher list based on system capabilities:

-        payload = {"binarize": self.binarize,
-                   "encodings": list(c for c in SupportedEncodings),
-                   "ciphers": list(c for c in SupportedCiphers)}
+        from hivemind_bus_client.encryption import optimal_ciphers
+        payload = {"binarize": self.binarize,
+                   "encodings": list(c for c in SupportedEncodings),
+                   "ciphers": list(optimal_ciphers())}
hivemind_bus_client/encryption.py (2)

12-18: LGTM! Well-defined cipher constants.

Good practice using named constants for cipher-specific values. This makes the code more maintainable and reduces the risk of errors.


350-351: ⚠️ Potential issue

Fix incorrect docstring.

The docstring incorrectly states AES-GCM-128 instead of ChaCha20-Poly1305.

Apply this diff:

-    Decrypts ciphertext encrypted using AES-GCM-128.
+    Decrypts ciphertext encrypted using ChaCha20-Poly1305.

Likely invalid or redundant comment.

hivemind_bus_client/client.py (3)

20-22: LGTM! Import changes align with configurable cipher support.

The imports from the encryption module provide the necessary components for implementing configurable ciphers and encodings.


108-109: Make cipher and encoding configurable through constructor.

The hardcoded defaults limit the configurability promised in the PR objectives.

This issue was previously identified. Please refer to the earlier review comment suggesting the addition of json_cipher and bin_cipher parameters to the constructor.


374-374: Verify cipher support during handshake.

While the cipher parameters are correctly passed to encryption functions, there's no verification that the receiving end supports the configured cipher. This could lead to communication failures if incompatible ciphers are used.

Run this script to check if cipher negotiation is implemented in the handshake protocol:

Consider implementing cipher capability exchange during the handshake to ensure both ends agree on supported ciphers.

Also applies to: 381-382

hivemind_bus_client/client.py Show resolved Hide resolved
Copy link
Contributor

@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 (2)
hivemind_bus_client/protocol.py (2)

3-3: Remove unused import

The Tuple import is not used in this file.

-from typing import Optional, Tuple
+from typing import Optional
🧰 Tools
🪛 Ruff (0.8.2)

3-3: typing.Tuple imported but unused

Remove unused import: typing.Tuple

(F401)


Line range hint 207-211: Consider implementing handshake preference configuration

The TODO comment indicates that handshake preference configuration is planned but not implemented. This would provide more flexibility in choosing between password and RSA handshakes.

Would you like me to help implement the handshake preference configuration? This could include:

  1. Adding configuration options for preferred handshake method
  2. Implementing logic to select between password and RSA based on preferences
  3. Adding validation for the configuration
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 9118883 and 7c6a58c.

📒 Files selected for processing (1)
  • hivemind_bus_client/protocol.py (5 hunks)
🧰 Additional context used
🪛 Ruff (0.8.2)
hivemind_bus_client/protocol.py

3-3: typing.Tuple imported but unused

Remove unused import: typing.Tuple

(F401)

🔇 Additional comments (2)
hivemind_bus_client/protocol.py (2)

12-12: LGTM: New encryption imports

The addition of encryption-related imports aligns well with the PR's objective of supporting configurable ciphers.


146-155: LGTM: Enhanced handshake payload with configurable encryption

The implementation properly supports:

  • Multiple encoding formats (base64 and hex)
  • Configurable ciphers
  • Both password and pubkey-based handshakes

Let's verify the cipher selection implementation:

✅ Verification successful

Cipher selection implementation is secure and well-designed

The optimal_ciphers() implementation provides a robust cipher selection strategy:

  • Prioritizes hardware-accelerated AES when CPU supports it: AES-GCM > AES-CCM > ChaCha20-Poly1305
  • Falls back to ChaCha20-Poly1305 as primary cipher when AES hardware acceleration is unavailable
  • All supported ciphers (AES-GCM, AES-CCM, ChaCha20-Poly1305) are modern authenticated encryption algorithms

The implementation aligns with cryptographic best practices by:

  • Using authenticated encryption modes (GCM, CCM, Poly1305)
  • Considering hardware capabilities for optimal performance
  • Maintaining a secure fallback option with ChaCha20-Poly1305
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Verify the optimal_ciphers implementation
ast-grep --pattern 'def optimal_ciphers():
  $$$
'

Length of output: 52


Script:

#!/bin/bash
# Let's try searching for the function name with ripgrep
rg "optimal_ciphers" -A 5

Length of output: 1495


Script:

#!/bin/bash
# Let's check the CPU support function and cipher enum
rg "cpu_supports_AES|SupportedCiphers" -A 3

Length of output: 8391

hivemind_bus_client/protocol.py Outdated Show resolved Hide resolved
Copy link
Contributor

@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

♻️ Duplicate comments (1)
hivemind_bus_client/protocol.py (1)

190-192: ⚠️ Potential issue

Security: Remove key size from logs.

While debug logging of encoding and cipher choices is helpful, logging the key size might expose sensitive information in log files.

-            LOG.debug(f"Key size: {len(self.pswd_handshake.secret) * 8}bit")
+            LOG.debug("Handshake completed successfully")
🧹 Nitpick comments (4)
hivemind_bus_client/protocol.py (2)

3-3: Remove unused import.

The Tuple import is not used in the code.

-from typing import Optional, Tuple
+from typing import Optional
🧰 Tools
🪛 Ruff (0.8.2)

3-33: typing.Tuple imported but unused

Remove unused import: typing.Tuple

(F401)


211-211: Address TODO comments about handshake preferences.

The TODO comments indicate missing functionality for:

  1. Preference flags for pre-shared keys vs handshake
  2. Preference flags for password vs RSA handshake

Would you like me to help implement these features or create GitHub issues to track them?

hivemind_bus_client/encryption.py (2)

416-419: Simplify nested if statements.

The nested if statements can be combined using and for better readability.

-    if nonce:
-        if len(nonce) != CHACHA20_NONCE_SIZE:  # 92bits/12bytes per RFC7539
-            raise InvalidKeySize("CHACHA20-POLY1305 requires a 12-byte nonce per RFC7539")
+    if nonce and len(nonce) != CHACHA20_NONCE_SIZE:  # 92bits/12bytes per RFC7539
+        raise InvalidKeySize("CHACHA20-POLY1305 requires a 12-byte nonce per RFC7539")

Also applies to: 449-452

🧰 Tools
🪛 Ruff (0.8.2)

416-417417: Use a single if statement instead of nested if statements

Combine if statements using and

(SIM102)


459-459: Improve test code readability.

Avoid Yoda conditions for better readability.

-    print("JSON-B64" == SupportedEncodings.JSON_B64)
+    print(SupportedEncodings.JSON_B64 == "JSON-B64")
🧰 Tools
🪛 Ruff (0.8.2)

459-459459: Yoda condition detected

Rewrite as SupportedEncodings.JSON_B64 == "JSON-B64"

(SIM300)

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 7c6a58c and e11ca29.

📒 Files selected for processing (2)
  • hivemind_bus_client/encryption.py (1 hunks)
  • hivemind_bus_client/protocol.py (5 hunks)
🧰 Additional context used
🪛 Ruff (0.8.2)
hivemind_bus_client/protocol.py

3-33: typing.Tuple imported but unused

Remove unused import: typing.Tuple

(F401)

hivemind_bus_client/encryption.py

416-417417: Use a single if statement instead of nested if statements

Combine if statements using and

(SIM102)


449-450450: Use a single if statement instead of nested if statements

Combine if statements using and

(SIM102)


459-459459: Yoda condition detected

Rewrite as SupportedEncodings.JSON_B64 == "JSON-B64"

(SIM300)

🔇 Additional comments (5)
hivemind_bus_client/protocol.py (1)

146-154: LGTM: Handshake payload construction is well-structured.

The handshake payload includes all necessary information for cipher and encoding negotiation.

hivemind_bus_client/encryption.py (4)

12-33: Well-structured cipher constants and CPU detection.

Good practices observed:

  • Clear separation of cipher-specific constants
  • Hardware capability detection for optimal cipher selection
  • Constants follow RFC specifications

267-286: LGTM: Robust error handling implementation.

Good practices observed:

  • Clear separation between key size validation and other encryption errors
  • Consistent error handling across different cipher implementations
  • Proper exception chaining using raise ... from ...

46-58: LGTM: Strong cryptographic implementation.

The implementation follows security best practices:

  • Adherence to RFC specifications
  • Proper validation of key sizes and nonce lengths
  • Support for modern ciphers (ChaCha20-Poly1305)
  • Hardware-aware cipher selection

Also applies to: 413-419


429-430: 🛠️ Refactor suggestion

Fix incorrect docstring in ChaCha20-Poly1305 decryption.

The docstring incorrectly states it decrypts AES-GCM-128 instead of ChaCha20-Poly1305.

-    Decrypts ciphertext encrypted using AES-GCM-128.
+    Decrypts ciphertext encrypted using ChaCha20-Poly1305.

Likely invalid or redundant comment.

@github-actions github-actions bot added feature and removed feature labels Jan 3, 2025
Copy link
Contributor

@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 (4)
hivemind_bus_client/z85b.py (2)

98-99: Raise exceptions with explicit chaining.

Currently, the code raises a new Z85DecodeError from a KeyError without explicitly referencing the original exception. This can make debugging more difficult.

-                except KeyError as e:
-                    raise Z85DecodeError(f"Invalid byte code: {e.args[0]!r}")
+                except KeyError as err:
+                    raise Z85DecodeError(f"Invalid byte code: {err.args[0]!r}") from err
🧰 Tools
🪛 Ruff (0.8.2)

99-99: Within an except clause, raise exceptions with raise ... from err or raise ... from None to distinguish them from errors in exception handling

(B904)


85-108: Validate large input processing.

When handling large byte strings, operations like re.sub(rb'\s+', b'', z85bytes...) and packing/unpacking in memory might be resource-intensive. Ensure that this approach meets performance needs or consider a streaming or chunk-based architecture if extremely large data must be handled.

🧰 Tools
🪛 Ruff (0.8.2)

99-99: Within an except clause, raise exceptions with raise ... from err or raise ... from None to distinguish them from errors in exception handling

(B904)

hivemind_bus_client/encryption.py (2)

443-445: Consolidate nested if statements.

The static analysis suggests combining nested if nonce checks with the if len(nonce) ....

-    if nonce:
-        if len(nonce) != CHACHA20_NONCE_SIZE:
-            raise InvalidKeySize("CHACHA20-POLY1305 requires a 12-byte nonce per RFC7539")
+    if nonce and len(nonce) != CHACHA20_NONCE_SIZE:
+        raise InvalidKeySize("CHACHA20-POLY1305 requires a 12-byte nonce per RFC7539")
🧰 Tools
🪛 Ruff (0.8.2)

443-444: Use a single if statement instead of nested if statements

Combine if statements using and

(SIM102)


486-486: Re-check Yoda condition.

Static analysis flags “"JSON-B64" == SupportedEncodings.JSON_B64” as a Yoda condition. Usually, we write it as SupportedEncodings.JSON_B64 == "JSON-B64" or compare directly to the enum member. Consider aligning with typical equality conventions.

🧰 Tools
🪛 Ruff (0.8.2)

486-486: Yoda condition detected

Rewrite as SupportedEncodings.JSON_B64 == "JSON-B64"

(SIM300)

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between e11ca29 and 2b34304.

📒 Files selected for processing (3)
  • hivemind_bus_client/encryption.py (1 hunks)
  • hivemind_bus_client/exceptions.py (1 hunks)
  • hivemind_bus_client/z85b.py (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • hivemind_bus_client/exceptions.py
🧰 Additional context used
🪛 Ruff (0.8.2)
hivemind_bus_client/z85b.py

99-99: Within an except clause, raise exceptions with raise ... from err or raise ... from None to distinguish them from errors in exception handling

(B904)

hivemind_bus_client/encryption.py

443-444: Use a single if statement instead of nested if statements

Combine if statements using and

(SIM102)


476-477: Use a single if statement instead of nested if statements

Combine if statements using and

(SIM102)


486-486: Yoda condition detected

Rewrite as SupportedEncodings.JSON_B64 == "JSON-B64"

(SIM300)

🔇 Additional comments (4)
hivemind_bus_client/z85b.py (1)

53-55: Clarify handling of arbitrary data types for rawbytes.

rawbytes = bytearray(rawbytes) if isinstance(rawbytes, (bytes, str)) else rawbytes may lead to unexpected behavior if users pass a different iterable type (e.g., memoryview, array.array). Consider clarifying or validating the input to avoid edge cases.

hivemind_bus_client/encryption.py (3)

172-172: Docstring mismatch for key truncation.

The docstring states “The encryption key, up to 16 bytes. Longer keys will be truncated,” but the code enforces 16/24/32 valid lengths and raises an InvalidKeySize if violated. This discrepancy may confuse maintainers or users.

Do you want to revise the docstring or implement actual key truncation?


476-478: Avoid nested if for nonce check.

Same pattern as lines 443-445.

🧰 Tools
🪛 Ruff (0.8.2)

476-477: Use a single if statement instead of nested if statements

Combine if statements using and

(SIM102)


456-456: ⚠️ Potential issue

Correct cipher reference in the docstring.

The docstring for decrypt_ChaCha20_Poly1305 incorrectly states “Decrypts ciphertext encrypted using AES-GCM-128.” This can cause confusion for maintainers.

-    Decrypts ciphertext encrypted using AES-GCM-128.
+    Decrypts ciphertext encrypted using ChaCha20-Poly1305.

Likely invalid or redundant comment.

@JarbasAl JarbasAl changed the title feat:chacha20 feat:add chacha20 cipher + z85 encoding Jan 3, 2025
@github-actions github-actions bot added feature and removed feature labels Jan 3, 2025
Copy link
Contributor

@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 (6)
hivemind_bus_client/protocol.py (3)

3-3: Remove unused import

The Tuple import is not used in this file.

-from typing import Optional, Tuple
+from typing import Optional
🧰 Tools
🪛 Ruff (0.8.2)

3-3: typing.Tuple imported but unused

Remove unused import: typing.Tuple

(F401)


212-212: Security: Track crypto configuration TODOs

There are important security-related TODOs that should be tracked and implemented:

  1. Add configuration flag for pre-shared key preference
  2. Add configuration flag for handshake type preference (password vs RSA)

These features would enhance the security configuration flexibility.

Would you like me to create GitHub issues to track these security enhancements?


Line range hint 289-297: Improve crypto error handling specificity

The current try-except block catches all exceptions, making it difficult to distinguish between crypto failures and other errors. Consider handling specific crypto exceptions.

             try:
                 ciphertext = pybase64.b64decode(pload["ciphertext"])
                 signature = pybase64.b64decode(pload["signature"])
                 private_key = load_RSA_key(self.identity.private_key)
                 decrypted = decrypt_RSA(private_key, ciphertext).decode("utf8")
                 message._payload = HiveMessage.deserialize(decrypted)
-            except:
+            except (ValueError, TypeError) as e:
+                # Handle malformed base64
+                LOG.error(f"Malformed base64 data: {e}")
+                return False
+            except Exception as e:
                 if k:
-                    LOG.error("failed to decrypt message!")
+                    LOG.error(f"Failed to decrypt message: {e}")
                 else:
-                    LOG.debug("failed to decrypt message, not for us")
+                    LOG.debug(f"Failed to decrypt message, not for us: {e}")
                 return False
🧰 Tools
🪛 Ruff (0.8.2)

3-3: typing.Tuple imported but unused

Remove unused import: typing.Tuple

(F401)

hivemind_bus_client/z85b.py (3)

22-35: Consider adding type hints to class variables

The class constants and mappings are well-organized and efficient. Consider adding type hints to improve code maintainability:

-    Z85CHARS = bytearray(b"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.-:+=^!/*?&<>()[]{}@%$#")
+    Z85CHARS: bytearray = bytearray(b"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.-:+=^!/*?&<>()[]{}@%$#")
-    Z85MAP = {char: idx for idx, char in enumerate(Z85CHARS)}
+    Z85MAP: dict[int, int] = {char: idx for idx, char in enumerate(Z85CHARS)}
-    _85s = [85 ** i for i in range(5)]
+    _85s: list[int] = [85 ** i for i in range(5)]

36-64: Add input validation for empty or None input

The encoding implementation is efficient and correctly handles padding. However, consider adding explicit validation for edge cases:

     @classmethod
     def encode(cls, rawbytes: Union[str, bytes]) -> bytes:
+        if not rawbytes:
+            return b''
+        if rawbytes is None:
+            raise ValueError("Input cannot be None")
         rawbytes = bytearray(rawbytes) if isinstance(rawbytes, (bytes, str)) else rawbytes

92-94: Improve exception chaining for better error tracking

The error handling is good, but could be improved by properly chaining exceptions to preserve the traceback:

-                except KeyError as e:
-                    raise Z85DecodeError(f"Invalid byte code: {e.args[0]!r}")
+                except KeyError as e:
+                    raise Z85DecodeError(f"Invalid byte code: {e.args[0]!r}") from e
🧰 Tools
🪛 Ruff (0.8.2)

93-93: Within an except clause, raise exceptions with raise ... from err or raise ... from None to distinguish them from errors in exception handling

(B904)

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 2b34304 and e93b1a3.

📒 Files selected for processing (3)
  • hivemind_bus_client/exceptions.py (2 hunks)
  • hivemind_bus_client/protocol.py (5 hunks)
  • hivemind_bus_client/z85b.py (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • hivemind_bus_client/exceptions.py
🧰 Additional context used
🪛 Ruff (0.8.2)
hivemind_bus_client/protocol.py

3-3: typing.Tuple imported but unused

Remove unused import: typing.Tuple

(F401)

hivemind_bus_client/z85b.py

93-93: Within an except clause, raise exceptions with raise ... from err or raise ... from None to distinguish them from errors in exception handling

(B904)

🔇 Additional comments (4)
hivemind_bus_client/protocol.py (2)

146-156: LGTM: Enhanced handshake with configurable encryption

The implementation properly supports multiple encoding formats and configurable ciphers, aligning with the PR objectives.


188-193: Security: Remove key size from logs

While logging encoding and cipher choices is helpful for debugging, logging the key size might expose sensitive information in log files.

            LOG.debug(f"Encoding: {self.hm.json_encoding}")
            LOG.debug(f"Cipher: {self.hm.cipher}")
-           LOG.debug(f"Key size: {len(self.pswd_handshake.secret) * 8}bit")
+           LOG.debug("Handshake completed successfully")
hivemind_bus_client/z85b.py (2)

1-20: Well-structured documentation and imports!

The file header clearly documents the differences from standard Z85, includes proper attribution, and has necessary imports with type hints.


1-102: Verify integration with ChaCha20 cipher system

The Z85b implementation looks solid, but let's verify its integration with the ChaCha20 cipher system mentioned in the PR objectives.

✅ Verification successful

Let me gather more information about the cipher system integration.


Let me search for one more specific aspect to complete the verification.


Z85B implementation is properly integrated with the encryption system

The verification shows that Z85B is well-integrated into the encryption system:

  1. Z85B is registered as a supported encoding via SupportedEncodings.JSON_Z85B
  2. The encoding/decoding functions are properly integrated through get_encoder() and get_decoder() functions
  3. The implementation supports the encryption workflow through JSON-based cipher output, alongside other encodings (B64, HEX)

The code shows a clean integration where:

  • Z85B is used as one of the supported JSON-based encryption encodings
  • The encoding/decoding functions are properly mapped to handle cipher outputs
  • The implementation maintains compatibility with the existing cipher system
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for Z85B usage in cipher implementations
rg -l "from.*z85b import|import.*z85b" | xargs rg "Z85B\." -A 5

# Look for ChaCha20 implementation using Z85B
ast-grep --pattern 'class $CIPHER_CLASS {
  $$$
  Z85B.$METHOD($$$)
  $$$
}'

Length of output: 486


Script:

#!/bin/bash
# Search for cipher implementations and their encoding usage
rg -l "class.*Cipher" | xargs rg "class.*Cipher" -A 10

# Search for encoding usage in cipher-related files
rg -l "Cipher" | xargs rg "encode|decode" -B 2 -A 2

# Look for tests involving Z85B and ciphers
fd test | xargs rg "Z85B.*Cipher|Cipher.*Z85B" -A 5

Length of output: 11927


Script:

#!/bin/bash
# Search for SupportedEncodings enum to understand Z85B integration
rg -A 10 "class SupportedEncodings"

# Search for actual usage of Z85B with encryption
rg "JSON_Z85B.*encrypt|encrypt.*JSON_Z85B" -A 5

Length of output: 918

🧰 Tools
🪛 Ruff (0.8.2)

93-93: Within an except clause, raise exceptions with raise ... from err or raise ... from None to distinguish them from errors in exception handling

(B904)

hivemind_bus_client/z85b.py Show resolved Hide resolved
JarbasAl added a commit to JarbasHiveMind/HiveMind-core that referenced this pull request Jan 3, 2025
@JarbasAl JarbasAl merged commit 23c1afb into dev Jan 3, 2025
1 check passed
JarbasAl added a commit to JarbasHiveMind/HiveMind-core that referenced this pull request Jan 3, 2025
* feat:cipher negotiation

companion to JarbasHiveMind/hivemind-websocket-client#50

* feat:cipher negotiation from config

* requirements.txt

* requirements.txt
This was referenced Jan 3, 2025
@JarbasAl JarbasAl deleted the feat/chacha20 branch January 8, 2025 21:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant