-
Notifications
You must be signed in to change notification settings - Fork 1
Mps backend #1
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
base: master
Are you sure you want to change the base?
Mps backend #1
Conversation
This commit adds an experimental backend for Apple Silicon using the PyTorch MPS (Metal Performance Shaders) backend. This is intended to allow BitCrack to run on Apple M-series GPUs. The new `MpsKeySearchDevice` class implements the `KeySearchDevice` interface and uses libtorch for computation. The build system has been updated to support building with libtorch when the `BUILD_MPS=1` flag is provided. Note: I haven't compiled or tested the code because the `libtorch` dependency was not available in my development environment. You will need to have libtorch installed and may need to adjust the `LIBTORCH_HOME` path in the `Makefile` to match your installation.
This commit fixes a linker error on macOS where the 'crypto' library could not be found. This was because the linker was not looking in the standard Homebrew installation path for OpenSSL. The Makefile is updated to include the Homebrew OpenSSL include and library paths when compiling on Darwin (macOS). This should allow the project to be built on macOS without manual configuration of OpenSSL paths, assuming OpenSSL was installed with Homebrew.
This commit fixes a linker error on Apple Silicon Macs where the 'crypto' library could not be found. This was because the linker was not looking in the correct Homebrew installation path for OpenSSL on Apple Silicon machines. The Makefile is updated to include the `/opt/homebrew/opt/openssl` include and library paths when compiling on Darwin (macOS). This should allow the project to be built on Apple Silicon Macs without manual configuration of OpenSSL paths, assuming OpenSSL was installed with Homebrew.
This commit fixes a linker error when building the 'addrgen' executable on macOS. The `LDFLAGS` variable, which contains the path to the OpenSSL library, was not being passed to the linker. This resulted in a "library not found" error for the 'crypto' library. The `AddrGen/Makefile` has been updated to include `LDFLAGS` in the linker command.
This commit fixes a build failure on macOS when using a libtorch installation from a miniconda environment. The `LIBTORCH_HOME` path in the `Makefile` was hardcoded to `/usr/local/libtorch`, which is not correct for this setup. The `Makefile` has been updated to point to the user-provided path for the miniconda-based libtorch installation. This should allow the project to be built successfully with the MPS backend.
This commit fixes a build failure when compiling with PyTorch. The version of PyTorch being used requires a C++17 compatible compiler, but the project was being built with C++11. The `Makefile` has been updated to use the `-std=c++17` flag, which should resolve the compilation errors related to C++17 features.
This commit fixes a build failure where the `MpsKeySearchDevice.h` header could not be found when compiling `main.cpp`. The `MpsKeySearchDevice` directory was not included in the `DIRS` variable in the main `Makefile`, which meant that the compiler was not looking in the correct directory for the header file. This has been corrected.
This commit fixes a linker error when building with the MPS backend on macOS. The torch libraries were not being linked in the correct order, which resulted in "undefined symbol" errors for torch functions. The `KeyFinder/Makefile` has been updated to explicitly link the torch libraries at the end of the linker command, which resolves the issue.
This commit fixes a linker error when building with the MPS backend on macOS. The torch libraries were being included twice in the linker command, which caused the linker to fail with "undefined symbol" errors. The `KeyFinder/Makefile` has been updated to remove the duplicate `-ltorch` and `-lc10` flags. The `LIBS` variable, which is passed from the main `Makefile`, already contains these flags, so they are not needed here.
WalkthroughThis change introduces a new Metal-based GPU backend for key searching, adding support for Apple's Metal API alongside existing CUDA and OpenCL backends. It includes new source files, build system updates, device enumeration and selection logic, and a Metal kernel for secp256k1 elliptic curve operations. Build scripts and device type enumerations are updated accordingly. Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant MainApp
participant DeviceManager
participant MetalKeySearchDevice
participant MetalAPI
User->>MainApp: Start key search (with Metal enabled)
MainApp->>DeviceManager: getDevices()
DeviceManager->>MetalAPI: Query system Metal devices
MetalAPI-->>DeviceManager: Return Metal device info
DeviceManager-->>MainApp: List devices (including Metal)
MainApp->>MetalKeySearchDevice: Instantiate device
MetalKeySearchDevice->>MetalAPI: Initialize Metal device, compile kernel
MainApp->>MetalKeySearchDevice: init(start, compression, stride)
loop For each step
MainApp->>MetalKeySearchDevice: doStep()
MetalKeySearchDevice->>MetalAPI: Dispatch kernel (generate_public_key)
MetalAPI-->>MetalKeySearchDevice: Kernel execution complete
MetalKeySearchDevice-->>MainApp: (Results pending: TODO)
end
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Poem
Note ⚡️ Unit Test Generation is now available in beta!Learn more here, or try it out under "Finishing Touches" below. 📜 Recent review detailsConfiguration used: CodeRabbit UI 📒 Files selected for processing (1)
✅ Files skipped from review due to trivial changes (1)
✨ Finishing Touches🧪 Generate unit tests
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. 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)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 4
🧹 Nitpick comments (5)
KeyFinder/DeviceManager.cpp (1)
64-76: Consider improving error handling for MPS device initialization.The MPS device detection logic follows the existing pattern well, but there are a few considerations:
- Setting
physicalId,memory, andcomputeUnitsto 0 might be misleading for users who expect meaningful device information- No exception handling around
torch::mps::is_available()- if this throws, it could crash the applicationConsider this improvement:
#ifdef BUILD_MPS - if(torch::mps::is_available()) { + try { + if(torch::mps::is_available()) { + DeviceManager::DeviceInfo device; + device.name = "Apple MPS"; + device.type = DeviceType::MPS; + device.id = deviceId; + device.physicalId = 0; // TODO: Get actual MPS device info if available + device.memory = 0; // TODO: Query MPS memory if possible + device.computeUnits = 0; // TODO: Query MPS compute units if possible + devices.push_back(device); + deviceId++; + } + } catch(const std::exception& ex) { + // Log warning but don't fail - MPS is optional + // Consider logging: "Warning: MPS device detection failed: " + ex.what() + }MpsKeySearchDevice/MpsKeySearchDevice.cpp (4)
4-10: Good device validation but consider more robust error handling.The constructor properly checks MPS availability before proceeding, which prevents runtime failures. However, there are a few suggestions:
- The exception type
KeySearchExceptionshould be properly included/declared- Consider logging device creation at a different level than stdout
MpsKeySearchDevice::MpsKeySearchDevice(int deviceId, uint64_t keysPerStep) : _device(torch::kMPS) { if (!torch::mps::is_available()) { throw KeySearchException("MPS device not available"); } this->_keysPerStep = keysPerStep; - std::cout << "MpsKeySearchDevice created" << std::endl; + // Consider using a logging framework instead of direct stdout }
12-14: Consider removing debug output from production code.The destructor logging to stdout may not be appropriate for production usage.
MpsKeySearchDevice::~MpsKeySearchDevice() { - std::cout << "MpsKeySearchDevice destroyed" << std::endl; + // Consider using a logging framework or removing debug output }
16-21: Initialization method is correct but has debug output.The parameter assignment logic is sound, but consider removing or replacing the debug output.
void MpsKeySearchDevice::init(const secp256k1::uint256 &start, int compression, const secp256k1::uint256 &stride) { this->_startKey = start; this->_compression = compression; this->_stride = stride; - std::cout << "MpsKeySearchDevice::init" << std::endl; }
46-50: Consider implementing actual memory information.While returning zeros is acceptable for a stub implementation, providing actual MPS device memory information would be more useful for users.
Consider querying PyTorch for MPS memory information:
void MpsKeySearchDevice::getMemoryInfo(uint64_t &freeMem, uint64_t &totalMem) { - // Not implemented for MPS - freeMem = 0; - totalMem = 0; + // TODO: Query actual MPS memory if PyTorch provides API + // For now, return reasonable defaults or query system memory + freeMem = 0; + totalMem = 0; }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (9)
AddrGen/Makefile(1 hunks)KeyFinder/DeviceManager.cpp(2 hunks)KeyFinder/DeviceManager.h(1 hunks)KeyFinder/Makefile(1 hunks)KeyFinder/main.cpp(2 hunks)Makefile(6 hunks)MpsKeySearchDevice/Makefile(1 hunks)MpsKeySearchDevice/MpsKeySearchDevice.cpp(1 hunks)MpsKeySearchDevice/MpsKeySearchDevice.h(1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (1)
MpsKeySearchDevice/MpsKeySearchDevice.cpp (2)
MpsKeySearchDevice/MpsKeySearchDevice.h (1)
MpsKeySearchDevice(7-28)KeyFinderLib/KeySearchDevice.h (1)
KeySearchException(10-25)
🪛 checkmake (0.2.2)
MpsKeySearchDevice/Makefile
[warning] 1-1: Missing required phony target "all"
(minphony)
[warning] 1-1: Missing required phony target "clean"
(minphony)
[warning] 1-1: Missing required phony target "test"
(minphony)
🔇 Additional comments (21)
AddrGen/Makefile (1)
4-4: LGTM! Standard build system improvement.Adding
${LDFLAGS}to the build command is a good practice that provides flexibility for additional linker flags, which is essential for the MPS backend integration.KeyFinder/DeviceManager.h (1)
25-26: LGTM! Clean extension of device type system.The addition of the
MPSdevice type follows the existing enum pattern and integrates well with the existingCUDAandOpenCLtypes.KeyFinder/Makefile (3)
10-10: LGTM! Consistent with build system improvements.Adding
${LDFLAGS}to the OpenCL build command maintains consistency with the broader build system updates.
14-18: Well-structured MPS build target.The new MPS build target follows the established pattern used for CUDA and OpenCL builds, with proper conditional compilation and appropriate library linking.
23-23: Clean target properly updated.The addition of
mpsKeyFinder.binto the clean target ensures proper cleanup of MPS-related build artifacts.KeyFinder/main.cpp (2)
23-25: Proper conditional compilation for MPS support.The conditional include for
MpsKeySearchDevice.hfollows the established pattern used for CUDA and OpenCL device headers.
258-262: Confirmed MpsKeySearchDevice constructor usage is correctThe constructor in MpsKeySearchDevice/MpsKeySearchDevice.h
MpsKeySearchDevice(int deviceId, uint64_t keysPerStep);matches the call in KeyFinder/main.cpp (line 260):
return new MpsKeySearchDevice(device.id, pointsPerThread);No changes required.
KeyFinder/DeviceManager.cpp (1)
11-13: LGTM! Consistent with existing conditional compilation pattern.The conditional inclusion of
<torch/torch.h>follows the same pattern as CUDA and OpenCL includes, maintaining consistency in the codebase structure.MpsKeySearchDevice/MpsKeySearchDevice.h (4)
1-3: LGTM! Proper header guard naming convention.The header guard follows a clear naming convention with underscores and matches the filename structure.
4-6: LGTM! Clean dependency management.The includes are minimal and appropriate - inheriting from the base class and including the required PyTorch headers.
7-15: Well-designed class structure with appropriate member variables.The private members effectively encapsulate the MPS device state:
- PyTorch device handle
- Key management variables (_startKey, _stride)
- Search configuration (_compression, _targets, _keysPerStep)
The design follows good encapsulation principles.
16-28: Complete and consistent public interface.The public method declarations properly override all virtual methods from the base
KeySearchDeviceclass, ensuring full interface compliance. The method signatures match the expected pattern for device implementations.MpsKeySearchDevice/MpsKeySearchDevice.cpp (3)
29-31: LGTM! Proper target conversion.The conversion from
std::settostd::vectoris handled correctly using the assign method.
38-44: LGTM! Simple accessor methods work correctly.Both
keysPerStep()andgetDeviceName()provide appropriate return values for their respective purposes.
52-54: LGTM! Correct key state access.The method correctly returns the current key state for external monitoring.
Makefile (6)
3-3: LGTM! MpsKeySearchDevice properly added to build directories.The addition of
MpsKeySearchDeviceto the DIRS variable ensures it gets included in the build process consistently with other components.
13-15: Good upgrade to C++17 and addition of LDFLAGS.The upgrade from C++11 to C++17 is necessary for modern PyTorch compatibility, and the new LDFLAGS variable provides better flexibility for platform-specific linking.
16-35: Comprehensive OS-specific configuration, but hardcoded paths need attention.The OS detection and platform-specific settings are well-structured. However, there are some concerns:
The hardcoded OpenSSL path
/opt/homebrew/opt/opensslassumes Homebrew installation on macOS. This may not work for all users.Consider making this configurable:
ifeq ($(UNAME_S),Darwin) # macOS-specific settings CXX=clang++ # Use Apple's OpenCL framework - LDFLAGS+=-framework OpenCL -L/opt/homebrew/opt/openssl/lib - CXXFLAGS+=-I/opt/homebrew/opt/openssl/include + LDFLAGS+=-framework OpenCL + # Try multiple common OpenSSL locations + ifneq ($(wildcard /opt/homebrew/opt/openssl),) + LDFLAGS+=-L/opt/homebrew/opt/openssl/lib + CXXFLAGS+=-I/opt/homebrew/opt/openssl/include + else ifneq ($(wildcard /usr/local/opt/openssl),) + LDFLAGS+=-L/usr/local/opt/openssl/lib + CXXFLAGS+=-I/usr/local/opt/openssl/include + endif
86-90: LGTM! Proper conditional MPS build configuration.The conditional MPS build setup correctly adds the necessary compiler flags and library dependencies when BUILD_MPS=1.
101-102: LGTM! Consistent build target pattern.The new MPS build target follows the same dependency pattern as other device targets, ensuring proper build ordering.
129-131: LGTM! Proper integration with existing dependency system.The conditional addition of MPS dependencies maintains consistency with the existing CUDA and OpenCL patterns.
| void MpsKeySearchDevice::doStep() { | ||
| // This is where the magic happens | ||
| // For now, just advance the key | ||
| _startKey = _startKey + _stride; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Critical issue: Missing actual MPS computation implementation.
The doStep() method is the core of the key search functionality, but it only advances the key without performing any actual cryptographic operations using MPS. This renders the device non-functional for its intended purpose.
The current implementation only advances the key but doesn't perform the actual elliptic curve operations or address generation that should utilize MPS. You need to implement:
- EC point multiplication using MPS/PyTorch tensors
- Address generation from public keys
- Target matching logic
- Result collection
This is a placeholder that needs substantial implementation work.
🤖 Prompt for AI Agents
In MpsKeySearchDevice/MpsKeySearchDevice.cpp around lines 23 to 27, the doStep()
method currently only increments the key without performing any cryptographic
operations. To fix this, implement the core MPS computation by performing
elliptic curve point multiplication using MPS or PyTorch tensors, generate
addresses from the resulting public keys, apply the target matching logic to
check for desired keys, and collect any matching results. Replace the
placeholder increment with this full cryptographic processing workflow.
| size_t MpsKeySearchDevice::getResults(std::vector<KeySearchResult> &results) { | ||
| // Not implemented yet | ||
| return 0; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Critical issue: Results method is unimplemented.
The getResults() method always returns 0, meaning no search results will ever be reported, even if matches are found.
This method needs to be implemented to return actual search results. The current stub implementation means the device will never report finding target addresses, making it non-functional.
🤖 Prompt for AI Agents
In MpsKeySearchDevice/MpsKeySearchDevice.cpp around lines 33 to 36, the
getResults() method is currently a stub that always returns 0, so it does not
return any actual search results. Implement this method to populate the results
vector with the found KeySearchResult objects and return the count of these
results to correctly report matches found by the device.
This commit refactors the build process for the MPS backend to address a persistent linker error on macOS. Instead of modifying the global `LIBS` variable, the torch library path and libraries are now explicitly added to the linker command in the `KeyFinder/Makefile`. This makes the build process for the `mpsKeyFinder` executable more self-contained and should resolve the "undefined symbol" errors by ensuring the correct library link order.
There was a problem hiding this 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
♻️ Duplicate comments (1)
Makefile (1)
70-73: Hard-codedLIBTORCH_HOMEpath still present
Same portability issue previously reported: a user-specific absolute path will break every other workstation / CI image.See prior review; please make this configurable or auto-detected.
🧹 Nitpick comments (1)
Makefile (1)
16-35: macOS section: duplicated-lstdc++, absent RTTI flags, and OpenSSL path hard-wired
LIBS+=-lstdc++whileclang++already linkslibc++by default; this may pull in two C++ std-libs.- If OpenSSL is installed elsewhere (Intel Homebrew prefix, MacPorts, system SDK) the hard path fails.
- Consider
-stdlib=libc++to avoid mis-linking withlibstdc++.Worth revisiting before wider distribution.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
KeyFinder/Makefile(1 hunks)Makefile(6 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- KeyFinder/Makefile
Makefile
Outdated
| ifeq ($(BUILD_MPS),1) | ||
| TARGETS:=${TARGETS} dir_mpsKeySearchDevice | ||
| CXXFLAGS:=${CXXFLAGS} -I${LIBTORCH_INCLUDE} -I${LIBTORCH_INCLUDE}/torch/csrc/api/include | ||
| endif | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
MPS build missing Torch libraries in link flags
CXXFLAGS adds the Torch include dirs, but neither LIBS nor LDFLAGS receive ${LIBTORCH_LIB} or the required -ltorch -ltorch_cpu -lc10 set. Any target that links against MpsKeySearchDevice will fail with “undefined symbol” errors.
ifeq ($(BUILD_MPS),1)
TARGETS:=${TARGETS} dir_mpsKeySearchDevice
CXXFLAGS:=${CXXFLAGS} -I${LIBTORCH_INCLUDE} -I${LIBTORCH_INCLUDE}/torch/csrc/api/include
+ LIBS+=-L${LIBTORCH_LIB} -ltorch -ltorch_cpu -lc10
+ LDFLAGS+=-L${LIBTORCH_LIB} -ltorch -ltorch_cpu -lc10
endifMake sure ${LIBTORCH_LIB} is exported so sub-Makefiles inherit it.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| ifeq ($(BUILD_MPS),1) | |
| TARGETS:=${TARGETS} dir_mpsKeySearchDevice | |
| CXXFLAGS:=${CXXFLAGS} -I${LIBTORCH_INCLUDE} -I${LIBTORCH_INCLUDE}/torch/csrc/api/include | |
| endif | |
| ifeq ($(BUILD_MPS),1) | |
| TARGETS:=${TARGETS} dir_mpsKeySearchDevice | |
| CXXFLAGS:=${CXXFLAGS} -I${LIBTORCH_INCLUDE} -I${LIBTORCH_INCLUDE}/torch/csrc/api/include | |
| LIBS+=-L${LIBTORCH_LIB} -ltorch -ltorch_cpu -lc10 | |
| LDFLAGS+=-L${LIBTORCH_LIB} -ltorch -ltorch_cpu -lc10 | |
| endif |
🤖 Prompt for AI Agents
In the Makefile around lines 86 to 90, the MPS build section adds Torch include
directories to CXXFLAGS but does not add the necessary Torch libraries to LIBS
or LDFLAGS, causing linking errors. To fix this, append ${LIBTORCH_LIB} and the
required libraries (-ltorch -ltorch_cpu -lc10) to the LIBS or LDFLAGS variables
within the ifeq block. Also, ensure that ${LIBTORCH_LIB} is exported so that
sub-Makefiles inherit it properly.
This commit addresses several issues identified in the code review for the new MPS backend. The following changes have been made: - **Makefile:** - The `LIBTORCH_HOME` path is now configurable and defaults to the user's miniconda environment. - The C++ standard for `nvcc` has been updated to C++17 to match the rest of the project. - The torch libraries are now correctly added to the `LIBS` variable for the MPS build. - **DeviceManager:** - Added a `try...catch` block around the `torch::mps::is_available()` call to prevent crashes if torch throws an exception. - Added `TODO` comments to indicate that the MPS device information is not yet fully implemented. - **MpsKeySearchDevice:** - Replaced `std::cout` with the existing `Logger` for consistency. - Added `TODO` comments to mark the unimplemented `doStep` and `getResults` methods. - Added `.PHONY` targets to the `MpsKeySearchDevice/Makefile` for `all` and `clean`. These changes should improve the robustness and portability of the build process for the MPS backend.
This commit addresses several issues identified in the code review for the new MPS backend. The following changes have been made: - **Makefile:** - The `LIBTORCH_HOME` path is now configurable and defaults to the user's miniconda environment. - The C++ standard for `nvcc` has been updated to C++17 to match the rest of the project. - The torch libraries are now correctly added to the `LIBS` variable for the MPS build. - **DeviceManager:** - Added a `try...catch` block around the `torch::mps::is_available()` call to prevent crashes if torch throws an exception. - Added `TODO` comments to indicate that the MPS device information is not yet fully implemented. - **MpsKeySearchDevice:** - Replaced `std::cout` with the existing `Logger` for consistency. - Added `TODO` comments to mark the unimplemented `doStep` and `getResults` methods. - Added `.PHONY` targets to the `MpsKeySearchDevice/Makefile` for `all` and `clean`. These changes should improve the robustness and portability of the build process for the MPS backend.
This commit removes the explicit linking of torch libraries from the `KeyFinder/Makefile`. These libraries are already included in the `LIBS` variable from the main `Makefile`, and the duplication was causing linker errors on macOS. This change should resolve the "undefined symbol" errors for torch functions by ensuring that the libraries are linked only once and in the correct order.
There was a problem hiding this 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 (2)
MpsKeySearchDevice/MpsKeySearchDevice.cpp (2)
23-30: Critical issue: Missing actual MPS computation implementation.The
doStep()method only advances the key without performing any actual cryptographic operations using MPS. This renders the device non-functional for its intended purpose.
36-41: Critical issue: Results method is unimplemented.The
getResults()method always returns 0, meaning no search results will ever be reported, even if matches are found.
🧹 Nitpick comments (1)
Makefile (1)
71-73: Good: Libtorch path is now configurable via environment variable.The use of
?=allows overriding via environment variable, addressing the portability issue. Consider adding auto-detection for better user experience:# Libtorch variables LIBTORCH_HOME?=/Users/haq/miniconda3/lib/python3.12/site-packages/torch + +# Auto-detect if not specified and python/torch available +ifeq ($(LIBTORCH_HOME),/Users/haq/miniconda3/lib/python3.12/site-packages/torch) + PYTHON_TORCH_PATH := $(shell python -c "import torch; print(torch.__path__[0])" 2>/dev/null) + ifneq ($(PYTHON_TORCH_PATH),) + LIBTORCH_HOME := $(PYTHON_TORCH_PATH) + endif +endif
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (5)
KeyFinder/DeviceManager.cpp(2 hunks)KeyFinder/Makefile(1 hunks)Makefile(6 hunks)MpsKeySearchDevice/Makefile(1 hunks)MpsKeySearchDevice/MpsKeySearchDevice.cpp(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
- KeyFinder/DeviceManager.cpp
- KeyFinder/Makefile
🧰 Additional context used
🧬 Code Graph Analysis (1)
MpsKeySearchDevice/MpsKeySearchDevice.cpp (2)
MpsKeySearchDevice/MpsKeySearchDevice.h (1)
MpsKeySearchDevice(7-28)KeyFinderLib/KeySearchDevice.h (1)
KeySearchException(10-25)
🪛 checkmake (0.2.2)
MpsKeySearchDevice/Makefile
[warning] 1-1: Missing required phony target "test"
(minphony)
🔇 Additional comments (3)
MpsKeySearchDevice/Makefile (1)
1-15: Well-structured Makefile with proper phony targets.The Makefile correctly implements the build process with appropriate .PHONY declarations and follows the project's build patterns.
Makefile (2)
13-41: Good: C++ standard is now consistent across all compilers.The upgrade to C++17 for both CXX and NVCC resolves the previous standard mismatch issue. The OS-specific settings appropriately handle platform differences.
86-90: Ensure all required LibTorch libraries are linked for MPSThe current
LIBSline in your Makefile only links-ltorchand-lc10, but a LibTorch MPS build often ships with additional libraries (for example,torch_cpufor CPU fallback or a backend-specific library). Please verify and update:
- Inspect your
$(LIBTORCH_LIB)directory:ls $(LIBTORCH_LIB) | grep -E 'torch|c10'- If you see
libtorch_cpu.*, add-ltorch_cputoLIBS.- If there’s a backend-specific library (e.g.
libc10_mps.*), add-lc10_mps.This will ensure you won’t encounter missing-symbol errors when running on MPS.
This commit refactors the build process for the MPS backend to further isolate the torch library linking and hopefully resolve the persistent linker errors on macOS. The torch-related `LIBS` modifications have been removed from the main `Makefile`, and the library path and libraries are now added directly to the `KeyFinder/Makefile`. This makes the `mpsKeyFinder` build command self-contained and should prevent any issues with linker flag ordering.
There was a problem hiding this 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
♻️ Duplicate comments (2)
Makefile (2)
86-90: Torch libraries still not linked – build will fail (undefined symbol)
Previous review flagged this; the include paths were added but-L${LIBTORCH_LIB} -ltorch -ltorch_cpu -lc10are still missing.ifeq ($(BUILD_MPS),1) TARGETS:=${TARGETS} dir_mpsKeySearchDevice CXXFLAGS:=${CXXFLAGS} -I${LIBTORCH_INCLUDE} -I${LIBTORCH_INCLUDE}/torch/csrc/api/include + LIBS+=-L${LIBTORCH_LIB} -ltorch -ltorch_cpu -lc10 + LDFLAGS+=-L${LIBTORCH_LIB} -ltorch -ltorch_cpu -lc10 endif
70-73: DefaultLIBTORCH_HOMEstill points to a personal path – add auto-detection fallback
?=allows override, but CI & fresh clones will still default to/Users/haq/..., breaking non-HaQ machines. Provide detection:-LIBTORCH_HOME?=/Users/haq/miniconda3/lib/python3.12/site-packages/torch +ifndef LIBTORCH_HOME + LIBTORCH_HOME:=$(shell python - <<'PY' 2>/dev/null +import importlib.util, sys +spec = importlib.util.find_spec("torch") +print(spec.submodule_search_locations[0] if spec else "", end="") +PY + ) +endif
🧹 Nitpick comments (1)
Makefile (1)
68-69:BUILD_MPSis exported but never initialised – default to 0 to avoid accidental enablement-export BUILD_MPS +BUILD_MPS ?= 0 +export BUILD_MPS
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
KeyFinder/Makefile(1 hunks)Makefile(6 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- KeyFinder/Makefile
Makefile
Outdated
| # Check for OS | ||
| ifeq ($(OS),Windows_NT) | ||
| # Windows-specific settings | ||
| else | ||
| UNAME_S := $(shell uname -s) | ||
| ifeq ($(UNAME_S),Linux) | ||
| # Linux-specific settings | ||
| LIBS+=-lstdc++ -lcrypto | ||
| endif | ||
| ifeq ($(UNAME_S),Darwin) | ||
| # macOS-specific settings | ||
| CXX=clang++ | ||
| # Use Apple's OpenCL framework | ||
| LDFLAGS+=-framework OpenCL -L/opt/homebrew/opt/openssl/lib | ||
| CXXFLAGS+=-I/opt/homebrew/opt/openssl/include | ||
| LIBS+=-lstdc++ -lcrypto | ||
| # Suppress unused parameter warnings that are common in cross-platform code | ||
| CXXFLAGS+=-Wno-unused-parameter | ||
| endif | ||
| endif |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
macOS section hard-codes OpenSSL include/lib paths
Relying on Homebrew’s default location (/opt/homebrew/…) breaks on Intel Macs and non-Homebrew setups. Prefer pkg-config or an overridable variable, e.g.:
- LDFLAGS+=-framework OpenCL -L/opt/homebrew/opt/openssl/lib
- CXXFLAGS+=-I/opt/homebrew/opt/openssl/include
+ OPENSSL_PREFIX ?=$(shell brew --prefix openssl@3 2>/dev/null)
+ ifneq ($(OPENSSL_PREFIX),)
+ LDFLAGS+=-framework OpenCL -L$(OPENSSL_PREFIX)/lib
+ CXXFLAGS+=-I$(OPENSSL_PREFIX)/include
+ else
+ $(warning OpenSSL not found – override OPENSSL_PREFIX)
+ endif🤖 Prompt for AI Agents
In the Makefile between lines 16 and 35, the macOS section hard-codes OpenSSL
include and library paths to Homebrew's default location, which fails on Intel
Macs or non-Homebrew setups. Replace these hard-coded paths with a call to
pkg-config to dynamically obtain the correct include and library flags for
OpenSSL, or define variables that can be overridden externally to specify these
paths. Update LDFLAGS and CXXFLAGS accordingly to use these dynamic or
variable-based paths instead of fixed ones.
Makefile
Outdated
| COMPUTE_CAP=86 | ||
| NVCC=nvcc | ||
| NVCCFLAGS=-std=c++11 -gencode=arch=compute_${COMPUTE_CAP},code=sm_${COMPUTE_CAP} -Xptxas="-v" -Xcompiler "${CXXFLAGS}" | ||
| NVCCFLAGS=-std=c++17 -gencode=arch=compute_${COMPUTE_CAP},code=sm_${COMPUTE_CAP} -Xptxas="-v" -Xcompiler "${CXXFLAGS}" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
NVCCFLAGS embeds $(CXXFLAGS) inside quoted string – may inject spaces twice
-Xcompiler "${CXXFLAGS}" keeps the quotes, so the resulting command line contains a literal space-separated string inside one argument, not multiple flags. Use unquoted expansion:
- NVCCFLAGS=-std=c++17 -gencode=arch=compute_${COMPUTE_CAP},code=sm_${COMPUTE_CAP} -Xptxas="-v" -Xcompiler "${CXXFLAGS}"
+ NVCCFLAGS=-std=c++17 -gencode=arch=compute_${COMPUTE_CAP},code=sm_${COMPUTE_CAP} -Xptxas="-v" -Xcompiler $(CXXFLAGS)🤖 Prompt for AI Agents
In the Makefile at line 41, the NVCCFLAGS variable includes the CXXFLAGS
variable inside quotes with -Xcompiler "${CXXFLAGS}", causing the entire
CXXFLAGS string to be treated as a single argument with embedded spaces. To fix
this, remove the quotes around ${CXXFLAGS} so that the flags are expanded as
separate arguments, changing -Xcompiler "${CXXFLAGS}" to -Xcompiler ${CXXFLAGS}.
This commit introduces a new, self-contained Makefile (`Makefile.mps`) for building the project with the MPS backend on macOS. This is a major refactoring of the build process to address the persistent linker errors that were occurring. The new `Makefile.mps` explicitly defines all the necessary include paths, library paths, and libraries for the MPS build, making it independent of the main `Makefile` and less prone to errors. The Makefiles in the subdirectories have also been simplified to only compile object files, with the `Makefile.mps` now responsible for creating the static libraries. To build with MPS support, use the command: `make -f Makefile.mps`
There was a problem hiding this 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)
MpsKeySearchDevice/Makefile (1)
1-1: Add the missingtestphony target for consistency and to silence lint warnings.
checkmakestill reports the absence of atesttarget. Even if you don’t intend to wire unit tests here, declaring the target avoids accidental filename clashes and keeps all component Makefiles uniform.-.PHONY: all clean +.PHONY: all clean test + +test: + @echo "No component-specific tests defined for $(NAME)"util/Makefile (1)
1-1: Declare atestphony target to match project-wide convention.-.PHONY: all clean +.PHONY: all clean test + +test: + @echo "No tests for util/"CmdParse/Makefile (1)
1-1: Add the standardtestphony target.Same rationale as other components—keeps lint quiet and targets uniform.
-.PHONY: all clean +.PHONY: all clean test + +test: + @echo "No tests for CmdParse/"Logger/Makefile (1)
1-1: Include a phonytesttarget for consistency.-.PHONY: all clean +.PHONY: all clean test + +test: + @echo "No tests for Logger/"secp256k1lib/Makefile (1)
1-1: Add the missingtestphony target.-.PHONY: all clean +.PHONY: all clean test + +test: + @echo "No tests for secp256k1lib/"Makefile.mps (1)
16-16: Consider making Homebrew paths configurable.The hardcoded Homebrew paths assume a specific installation location that may not be universal across different macOS setups (Intel vs Apple Silicon, custom Homebrew prefix).
Consider detecting the Homebrew prefix dynamically:
-INCLUDE += -I/opt/homebrew/opt/openssl/include +HOMEBREW_PREFIX?=$(shell brew --prefix 2>/dev/null || echo "/opt/homebrew") +INCLUDE += -I$(HOMEBREW_PREFIX)/opt/openssl/include-LDFLAGS=-L/opt/homebrew/opt/openssl/lib -L${LIBDIR} -L${LIBTORCH_LIB} +LDFLAGS=-L$(HOMEBREW_PREFIX)/opt/openssl/lib -L${LIBDIR} -L${LIBTORCH_LIB}Also applies to: 28-28
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (9)
AddressUtil/Makefile(1 hunks)CmdParse/Makefile(1 hunks)CryptoUtil/Makefile(1 hunks)KeyFinderLib/Makefile(1 hunks)Logger/Makefile(1 hunks)Makefile.mps(1 hunks)MpsKeySearchDevice/Makefile(1 hunks)secp256k1lib/Makefile(1 hunks)util/Makefile(1 hunks)
🧰 Additional context used
🪛 checkmake (0.2.2)
AddressUtil/Makefile
[warning] 1-1: Missing required phony target "test"
(minphony)
Logger/Makefile
[warning] 1-1: Missing required phony target "test"
(minphony)
CmdParse/Makefile
[warning] 1-1: Missing required phony target "test"
(minphony)
secp256k1lib/Makefile
[warning] 1-1: Missing required phony target "test"
(minphony)
util/Makefile
[warning] 1-1: Missing required phony target "test"
(minphony)
MpsKeySearchDevice/Makefile
[warning] 1-1: Missing required phony target "test"
(minphony)
CryptoUtil/Makefile
[warning] 1-1: Missing required phony target "test"
(minphony)
KeyFinderLib/Makefile
[warning] 1-1: Missing required phony target "test"
(minphony)
🔇 Additional comments (11)
MpsKeySearchDevice/Makefile (1)
6-9: Verify whether an archive or binary should be produced.
allcurrently stops at object files. Earlier revisions created a static lib (libMpsKeySearchDevice.a) which downstream link steps may still expect. Double-check the top-level build to ensure:
- Nothing depends on a missing archive.
- Linker command-lines were updated accordingly.
If an archive is still required, add:
all: lib$(NAME).a lib$(NAME).a: $(OBJS) $(AR) rcs $@ $^util/Makefile (1)
6-9: Confirm removal of static-library creation doesn’t break dependants.
The previous Makefile producedlibutil.a. With the archive step gone, any component that links-lutilwill now fail. Ensure either:
- Down-stream Makefiles were updated to link object files directly, or
- The archive rule is reinstated.
CmdParse/Makefile (1)
6-9: Double-check consumers oflibcmdparse.a.Dropping the archive step may break link lines such as
-lcmdparse. Verify build passes end-to-end or restore:all: libcmdparse.a libcmdparse.a: $(OBJS) $(AR) rcs $@ $^Logger/Makefile (1)
6-9: Ensure the build still links withoutliblogger.a.If other modules still expect the static library, re-introduce the archive rule or update their link flags.
secp256k1lib/Makefile (1)
6-9: Validate link expectations after droppinglibsecp256k1.a.Downstream code commonly links against a secp256k1 archive. Removing it may break the final link step; confirm or restore.
CryptoUtil/Makefile (1)
1-12: LGTM! Clean Makefile refactoring.The refactoring from explicit compilation loops to pattern rules is well-executed. The addition of
.PHONYdeclarations, theOBJSvariable derivation, and the simplified build structure all follow Makefile best practices.AddressUtil/Makefile (1)
1-12: LGTM! Consistent refactoring pattern.This Makefile follows the exact same refactoring pattern as other components, which ensures build system consistency across the project. The pattern rule and variable structure are correctly implemented.
KeyFinderLib/Makefile (1)
1-12: LGTM! Simplified and consistent build structure.The refactoring maintains consistency with other Makefiles while appropriately removing CUDA-specific build artifacts. The simplified clean target and pattern rule implementation are correct.
Makefile.mps (3)
56-57: LGTM! Well-structured executable build target.The executable build correctly depends on libraries and uses appropriate compiler and linker flags. The main source files are properly specified.
60-72: LGTM! Comprehensive clean target.The clean target properly cleans all component directories and removes output directories. The
.PHONYdeclaration is correctly specified.
37-40: Double-check the library build rule applies correctly to all $(LIBDIR)/lib%.a targetsI confirmed that each source directory exists and you’ve declared a static target for every library, but the
.SECONDEXPANSIONpattern is tricky—please verify:
- That
lib%.a:actually matches$(LIBDIR)/libname.a(ifLIBDIRisn’t empty, the rule may never fire).- That
$(addprefix $*, $(notdir $@))yields the intended object files (it should expand to something likefoo.o, not raw.cppor garbled names).- That running
make libsproduces archives containing the correct.ofiles (and thatar rvsis invoked with object files, not sources).
Makefile.mps
Outdated
| INCLUDE += -I/opt/homebrew/opt/openssl/include | ||
|
|
||
| # Libtorch paths | ||
| LIBTORCH_HOME?=/Users/haq/miniconda3/lib/python3.12/site-packages/torch |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Make Libtorch path configurable instead of hardcoded.
The hardcoded path /Users/haq/miniconda3/lib/python3.12/site-packages/torch makes the build system non-portable and will fail on other developer machines.
Consider this approach to make it configurable:
-LIBTORCH_HOME?=/Users/haq/miniconda3/lib/python3.12/site-packages/torch
+LIBTORCH_HOME?=$(shell python3 -c "import torch; print(torch.__path__[0])" 2>/dev/null || echo "/usr/local/lib/python3.12/site-packages/torch")Or provide clear documentation on how to set LIBTORCH_HOME environment variable.
🤖 Prompt for AI Agents
In Makefile.mps at line 19, the LIBTORCH_HOME path is hardcoded, reducing
portability. Modify the Makefile to allow LIBTORCH_HOME to be set via an
environment variable or a command-line argument, falling back to a default only
if not provided. Additionally, add documentation or comments explaining how to
set LIBTORCH_HOME externally to ensure other developers can configure it
correctly.
This commit fixes a runtime error on macOS where the `mpsBitCrack` executable could not find the `libtorch.dylib` library. The `Makefile.mps` has been updated to include the `-rpath` linker flag, which embeds the path to the torch libraries in the executable. This allows the dynamic linker to find the required libraries at runtime.
This commit fixes an issue where the `BUILD_MPS` preprocessor flag was not being defined when compiling the `mpsBitCrack` executable using `Makefile.mps`. This caused all the MPS-related code to be excluded from the build, resulting in no MPS device being detected at runtime. The `CXXFLAGS` in `Makefile.mps` has been updated to include the `-DBUILD_MPS` flag.
This commit introduces a new, simplified Makefile (`Makefile.mps_simple`) for building the project with the MPS backend on macOS. This is intended to be a more robust and easier-to-debug alternative to the complex, multi-level Makefiles that were causing persistent linker errors. The new `Makefile.mps_simple` is completely self-contained and explicitly defines all the necessary include paths, library paths, and libraries for the MPS build. To build with MPS support, use the command: `make -f Makefile.mps_simple`
This commit introduces an experimental backend for Apple Silicon using Apple's Metal framework. This is intended to allow BitCrack to run on Apple M-series GPUs. This commit includes: - A new `MetalKeySearchDevice` class that implements the `KeySearchDevice` interface. - A new `keysearch.metal` file containing the `secp256k1` cryptographic kernels written in Metal Shading Language. - A new `Makefile.metal` that is specifically designed to build the project with the Metal backend on macOS. To build with Metal support, use the command: `make -f Makefile.metal` Note: This code has not been compiled or tested on an Apple Silicon machine. You will need to have the Xcode toolchain installed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 6
♻️ Duplicate comments (1)
Makefile (1)
14-14: Verify LDFLAGS usageBased on past review comments,
LDFLAGSwas identified as unused. If it's still not referenced anywhere in the build system, consider removing it to avoid confusion.#!/bin/bash # Check if LDFLAGS is used anywhere in the makefiles rg -t make '\$\(LDFLAGS\)' --glob '*/Makefile' --glob 'Makefile'
🧹 Nitpick comments (3)
MetalKeySearchDevice/MetalKeySearchDevice.cpp (2)
95-95: Incomplete implementation of core functionalitySeveral critical methods are not implemented:
- Result checking after GPU computation (line 95)
- Target setting for address matching
- Result retrieval
- Next key tracking
These need to be implemented for the device to function properly.
Would you like me to help implement the missing functionality for result checking and target matching?
Also applies to: 105-110, 125-127
120-123: Implement Metal device memory queryingThe memory info method returns zeros. Metal provides APIs to query device memory.
void MetalKeySearchDevice::getMemoryInfo(uint64_t &freeMem, uint64_t &totalMem) { - freeMem = 0; - totalMem = 0; + // Metal doesn't provide direct memory queries like CUDA + // Use recommended memory limit as approximation + totalMem = _device->recommendedMaxWorkingSetSize(); + // Free memory estimation not directly available + freeMem = totalMem / 2; // Conservative estimate }MetalKeySearchDevice/keysearch.metal (1)
135-136: Improve readability with constant definitionsThe code repeatedly constructs
uint256_tfrom the_Parray inline.+// Define constant for modulus P +constant uint256_t P_CONST = { + _P[0], _P[1], _P[2], _P[3], _P[4], _P[5], _P[6], _P[7] +}; + uint256_t subModP256k(uint256_t a, uint256_t b) { uint borrow = 0; uint256_t c = sub256k(a, b, &borrow); if (borrow) { uint carry = 0; - add256k(c, (uint256_t){_P[0], _P[1], _P[2], _P[3], _P[4], _P[5], _P[6], _P[7]}, &carry); + add256k(c, P_CONST, &carry); } return c; }Also applies to: 145-146
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (9)
KeyFinder/DeviceManager.cpp(2 hunks)KeyFinder/DeviceManager.h(1 hunks)KeyFinder/Makefile(1 hunks)KeyFinder/main.cpp(2 hunks)Makefile(6 hunks)MetalKeySearchDevice/Makefile(1 hunks)MetalKeySearchDevice/MetalKeySearchDevice.cpp(1 hunks)MetalKeySearchDevice/MetalKeySearchDevice.h(1 hunks)MetalKeySearchDevice/keysearch.metal(1 hunks)
✅ Files skipped from review due to trivial changes (1)
- KeyFinder/Makefile
🚧 Files skipped from review as they are similar to previous changes (3)
- KeyFinder/DeviceManager.h
- KeyFinder/main.cpp
- KeyFinder/DeviceManager.cpp
🧰 Additional context used
🧬 Code Graph Analysis (2)
MetalKeySearchDevice/MetalKeySearchDevice.h (3)
KeyFinderLib/KeySearchDevice.h (1)
KeySearchDevice(37-63)KeyFinderLib/KeySearchTypes.h (1)
KeySearchTarget(40-94)secp256k1lib/secp256k1.h (2)
uint256(12-274)secp256k1(10-373)
MetalKeySearchDevice/MetalKeySearchDevice.cpp (3)
MetalKeySearchDevice/MetalKeySearchDevice.h (1)
MetalKeySearchDevice(7-33)KeyFinderLib/KeySearchDevice.h (1)
KeySearchException(10-25)secp256k1lib/secp256k1.h (1)
uint256(12-274)
🪛 checkmake (0.2.2)
MetalKeySearchDevice/Makefile
[warning] 1-1: Missing required phony target "test"
(minphony)
🔇 Additional comments (4)
MetalKeySearchDevice/Makefile (1)
1-13: LGTM!The Makefile follows standard conventions with proper phony targets and pattern rules. The static analysis warning about missing "test" target can be safely ignored as it's not required for all components.
Makefile (2)
58-63: Metal build configuration looks goodThe Metal build setup correctly:
- Switches to clang++ compiler (required for Metal)
- Updates to C++17 standard
- Adds necessary Metal and Foundation frameworks
- Suppresses unused parameter warnings
3-3: Metal integration properly structuredThe Metal device is correctly integrated into the build system with:
- Addition to DIRS list for includes
- Dedicated build target with proper dependencies
- Conditional inclusion in KEYFINDER_DEPS
Also applies to: 73-75, 101-103
MetalKeySearchDevice/MetalKeySearchDevice.h (1)
1-35: Well-structured Metal device headerThe header file is properly designed with:
- Correct header guards
- Appropriate Metal-cpp pointer types for Metal objects
- Proper inheritance from KeySearchDevice base class
- Complete virtual function declarations matching the interface
| uint256_t mulModP256k(uint256_t a, uint256_t b) { | ||
| uint256_t high, low; | ||
| multiply256(a, b, &high, &low); | ||
|
|
||
| // This is a simplified version of the modular reduction from the OpenCL code. | ||
| // A full implementation is required for correctness. | ||
| // For now, just return the low part of the product. | ||
| return low; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Incomplete modular arithmetic implementations
The modular multiplication and inverse functions are marked as simplified and will produce incorrect results.
These functions are critical for correctness. The modular multiplication needs proper Montgomery reduction for secp256k1, and the inverse needs to implement the extended Euclidean algorithm or Fermat's little theorem properly.
Would you like me to provide complete implementations of mulModP256k and invModP256k for secp256k1?
Also applies to: 165-168
🤖 Prompt for AI Agents
In MetalKeySearchDevice/keysearch.metal around lines 150 to 158 and 165 to 168,
the modular multiplication and inverse functions are currently simplified and
incorrect. Replace the simplified modular multiplication with a full Montgomery
reduction implementation tailored for secp256k1 to ensure correct modular
arithmetic. Similarly, implement the modular inverse function using the extended
Euclidean algorithm or Fermat's little theorem for accurate results. This will
ensure both functions perform correct modular operations as required.
| if (equal(*p1x, p2x)) { | ||
| if (equal(*p1y, p2y)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Function used before definition
The equal function is called on lines 183-184 but defined later at line 239. Metal requires functions to be defined before use.
Move the equal function definition before the point_add function:
+bool equal(uint256_t a, uint256_t b) {
+ for (int i = 0; i < 8; i++) {
+ if (a.v[i] != b.v[i]) {
+ return false;
+ }
+ }
+ return true;
+}
+
void point_add(thread uint256_t* p1x, thread uint256_t* p1y, uint256_t p2x, uint256_t p2y, thread uint256_t* p3x, thread uint256_t* p3y) {Also applies to: 239-246
🤖 Prompt for AI Agents
In MetalKeySearchDevice/keysearch.metal between lines 183 and 184, the function
'equal' is used before its definition at line 239, which Metal does not allow.
To fix this, move the entire 'equal' function definition so that it appears
before the 'point_add' function where it is first called. Also apply this change
to the function defined at lines 239-246 to ensure all functions are defined
before use.
| uint256_t tx, ty; | ||
| for (int i = 0; i < 256; i++) { | ||
| if ((private_key.v[7 - i / 32] >> (i % 32)) & 1) { | ||
| point_add(&px, &py, tx, ty, &px, &py); | ||
| } | ||
| point_add(&tx, &ty, tx, ty, &tx, &ty); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Uninitialized variables and incorrect scalar multiplication
The variables tx and ty are used without initialization, and the scalar multiplication algorithm is incorrect.
The double-and-add algorithm needs proper initialization and logic:
- uint256_t tx, ty;
+ // Initialize result to infinity (identity element)
+ uint256_t rx = { _INFINITY[0], _INFINITY[1], _INFINITY[2], _INFINITY[3], _INFINITY[4], _INFINITY[5], _INFINITY[6], _INFINITY[7] };
+ uint256_t ry = { _INFINITY[0], _INFINITY[1], _INFINITY[2], _INFINITY[3], _INFINITY[4], _INFINITY[5], _INFINITY[6], _INFINITY[7] };
+
+ // Current point being doubled
+ uint256_t qx = px;
+ uint256_t qy = py;
+
for (int i = 0; i < 256; i++) {
if ((private_key.v[7 - i / 32] >> (i % 32)) & 1) {
- point_add(&px, &py, tx, ty, &px, &py);
+ point_add(&rx, &ry, qx, qy, &rx, &ry);
}
- point_add(&tx, &ty, tx, ty, &tx, &ty);
+ // Double the current point
+ point_add(&qx, &qy, qx, qy, &qx, &qy);
}
+
+ px = rx;
+ py = ry;📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| uint256_t tx, ty; | |
| for (int i = 0; i < 256; i++) { | |
| if ((private_key.v[7 - i / 32] >> (i % 32)) & 1) { | |
| point_add(&px, &py, tx, ty, &px, &py); | |
| } | |
| point_add(&tx, &ty, tx, ty, &tx, &ty); | |
| } | |
| // Initialize result to infinity (identity element) | |
| uint256_t rx = { | |
| _INFINITY[0], _INFINITY[1], _INFINITY[2], _INFINITY[3], | |
| _INFINITY[4], _INFINITY[5], _INFINITY[6], _INFINITY[7] | |
| }; | |
| uint256_t ry = { | |
| _INFINITY[0], _INFINITY[1], _INFINITY[2], _INFINITY[3], | |
| _INFINITY[4], _INFINITY[5], _INFINITY[6], _INFINITY[7] | |
| }; | |
| // Current point being doubled | |
| uint256_t qx = px; | |
| uint256_t qy = py; | |
| for (int i = 0; i < 256; i++) { | |
| if ((private_key.v[7 - i / 32] >> (i % 32)) & 1) { | |
| point_add(&rx, &ry, qx, qy, &rx, &ry); | |
| } | |
| // Double the current point | |
| point_add(&qx, &qy, qx, qy, &qx, &qy); | |
| } | |
| px = rx; | |
| py = ry; |
🤖 Prompt for AI Agents
In MetalKeySearchDevice/keysearch.metal around lines 227 to 233, the variables
tx and ty are used without initialization, and the scalar multiplication logic
is incorrect. Initialize tx and ty to the base point coordinates before the loop
starts. Then, implement the double-and-add algorithm correctly by iterating over
each bit of the private key, doubling the current point each iteration, and
adding the base point to the result only when the corresponding bit is set.
Adjust the point_add calls accordingly to reflect this logic.
| MTL::Buffer* privateKeysBuffer = _device->newBuffer(_keysPerStep * sizeof(uint256_t), MTL::ResourceStorageModeShared); | ||
| MTL::Buffer* publicKeysXBuffer = _device->newBuffer(_keysPerStep * sizeof(uint256_t), MTL::ResourceStorageModeShared); | ||
| MTL::Buffer* publicKeysYBuffer = _device->newBuffer(_keysPerStep * sizeof(uint256_t), MTL::ResourceStorageModeShared); | ||
|
|
||
| // Generate private keys | ||
| uint256_t* privateKeys = (uint256_t*)privateKeysBuffer->contents(); | ||
| for (uint64_t i = 0; i < _keysPerStep; i++) { | ||
| privateKeys[i] = _startKey + _stride * i; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Type mismatch: use secp256k1::uint256 instead of uint256_t
The code uses uint256_t which doesn't match the Metal shader's struct definition. The private key arithmetic should use secp256k1::uint256 and properly handle the conversion to the shader's format.
The buffer allocation and private key generation need to be rewritten to:
- Define a proper struct matching the Metal shader's
uint256_t - Convert from
secp256k1::uint256to the shader format - Ensure proper memory layout compatibility
+ // Define struct matching Metal shader
+ struct metal_uint256_t {
+ uint32_t v[8];
+ };
+
// Create buffers
- MTL::Buffer* privateKeysBuffer = _device->newBuffer(_keysPerStep * sizeof(uint256_t), MTL::ResourceStorageModeShared);
- MTL::Buffer* publicKeysXBuffer = _device->newBuffer(_keysPerStep * sizeof(uint256_t), MTL::ResourceStorageModeShared);
- MTL::Buffer* publicKeysYBuffer = _device->newBuffer(_keysPerStep * sizeof(uint256_t), MTL::ResourceStorageModeShared);
+ MTL::Buffer* privateKeysBuffer = _device->newBuffer(_keysPerStep * sizeof(metal_uint256_t), MTL::ResourceStorageModeShared);
+ MTL::Buffer* publicKeysXBuffer = _device->newBuffer(_keysPerStep * sizeof(metal_uint256_t), MTL::ResourceStorageModeShared);
+ MTL::Buffer* publicKeysYBuffer = _device->newBuffer(_keysPerStep * sizeof(metal_uint256_t), MTL::ResourceStorageModeShared);
// Generate private keys
- uint256_t* privateKeys = (uint256_t*)privateKeysBuffer->contents();
+ metal_uint256_t* privateKeys = (metal_uint256_t*)privateKeysBuffer->contents();
for (uint64_t i = 0; i < _keysPerStep; i++) {
- privateKeys[i] = _startKey + _stride * i;
+ secp256k1::uint256 key = _startKey + _stride * i;
+ // Convert secp256k1::uint256 to metal_uint256_t
+ for (int j = 0; j < 8; j++) {
+ privateKeys[i].v[j] = key.v[j];
+ }
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| MTL::Buffer* privateKeysBuffer = _device->newBuffer(_keysPerStep * sizeof(uint256_t), MTL::ResourceStorageModeShared); | |
| MTL::Buffer* publicKeysXBuffer = _device->newBuffer(_keysPerStep * sizeof(uint256_t), MTL::ResourceStorageModeShared); | |
| MTL::Buffer* publicKeysYBuffer = _device->newBuffer(_keysPerStep * sizeof(uint256_t), MTL::ResourceStorageModeShared); | |
| // Generate private keys | |
| uint256_t* privateKeys = (uint256_t*)privateKeysBuffer->contents(); | |
| for (uint64_t i = 0; i < _keysPerStep; i++) { | |
| privateKeys[i] = _startKey + _stride * i; | |
| } | |
| // Define struct matching Metal shader | |
| struct metal_uint256_t { | |
| uint32_t v[8]; | |
| }; | |
| // Create buffers | |
| MTL::Buffer* privateKeysBuffer = _device->newBuffer(_keysPerStep * sizeof(metal_uint256_t), MTL::ResourceStorageModeShared); | |
| MTL::Buffer* publicKeysXBuffer = _device->newBuffer(_keysPerStep * sizeof(metal_uint256_t), MTL::ResourceStorageModeShared); | |
| MTL::Buffer* publicKeysYBuffer = _device->newBuffer(_keysPerStep * sizeof(metal_uint256_t), MTL::ResourceStorageModeShared); | |
| // Generate private keys | |
| metal_uint256_t* privateKeys = (metal_uint256_t*)privateKeysBuffer->contents(); | |
| for (uint64_t i = 0; i < _keysPerStep; i++) { | |
| secp256k1::uint256 key = _startKey + _stride * i; | |
| // Convert secp256k1::uint256 to metal_uint256_t | |
| for (int j = 0; j < 8; j++) { | |
| privateKeys[i].v[j] = key.v[j]; | |
| } | |
| } |
🤖 Prompt for AI Agents
In MetalKeySearchDevice/MetalKeySearchDevice.cpp around lines 61 to 69, replace
the use of uint256_t with secp256k1::uint256 for private key arithmetic to match
the Metal shader's struct definition. Define a struct that matches the shader's
uint256_t layout, convert each secp256k1::uint256 private key to this struct
format before storing it in the buffer, and ensure the buffer memory layout
aligns with the shader expectations for correct data interpretation.
|
|
||
| // Create a command buffer | ||
| MTL::CommandBuffer* commandBuffer = _commandQueue->commandBuffer(); | ||
| MTL::ComputeCommandEncoder*- commandEncoder = commandBuffer->computeCommandEncoder(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix syntax error in variable declaration
There's a syntax error with an errant dash character in the variable name.
- MTL::ComputeCommandEncoder*- commandEncoder = commandBuffer->computeCommandEncoder();
+ MTL::ComputeCommandEncoder* commandEncoder = commandBuffer->computeCommandEncoder();📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| MTL::ComputeCommandEncoder*- commandEncoder = commandBuffer->computeCommandEncoder(); | |
| MTL::ComputeCommandEncoder* commandEncoder = commandBuffer->computeCommandEncoder(); |
🤖 Prompt for AI Agents
In MetalKeySearchDevice/MetalKeySearchDevice.cpp at line 73, the variable
declaration for commandEncoder contains an incorrect dash character before the
variable name. Remove the dash so that the declaration correctly reads as a
pointer to MTL::ComputeCommandEncoder named commandEncoder without any
extraneous characters.
| uint64_t MetalKeySearchDevice::keysPerStep() { | ||
| return 0; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Return actual keys per step value
The method returns 0 instead of the stored _keysPerStep value.
uint64_t MetalKeySearchDevice::keysPerStep() {
- return 0;
+ return _keysPerStep;
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| uint64_t MetalKeySearchDevice::keysPerStep() { | |
| return 0; | |
| } | |
| uint64_t MetalKeySearchDevice::keysPerStep() { | |
| return _keysPerStep; | |
| } |
🤖 Prompt for AI Agents
In MetalKeySearchDevice/MetalKeySearchDevice.cpp at lines 112 to 114, the
keysPerStep() method incorrectly returns 0 instead of the actual stored value.
Modify the method to return the member variable _keysPerStep instead of 0 to
reflect the correct number of keys per step.
This commit adds the `Makefile.metal` file, which is a self-contained Makefile for building the project with the Metal backend on macOS. This Makefile is intended to provide a more robust and easier-to-debug build process than the previous approach of modifying the main Makefile. To build with Metal support, use the command: `make -f Makefile.metal`
Summary by CodeRabbit
New Features
Chores