Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions FOUND.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
0x000000000000000000000000000000000000000000000000006ABE1F9B67E114
71 changes: 64 additions & 7 deletions IntGroup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@ using namespace std;

IntGroup::IntGroup(int size) {
this->size = size;
subp = (Int *)malloc(size * sizeof(Int));
// Use aligned allocation for better SIMD performance
if (posix_memalign((void**)&subp, 64, size * sizeof(Int)) != 0) {
subp = (Int *)malloc(size * sizeof(Int));
}
}

IntGroup::~IntGroup() {
Expand All @@ -23,18 +26,72 @@ void IntGroup::ModInv() {
Int inverse;

subp[0].Set(&ints[0]);
for (int i = 1; i < size; i++) {
subp[i].ModMulK1(&subp[i - 1], &ints[i]);

// Unroll small loops for better performance
if (size >= 8) {
for (int i = 1; i < size; i += 8) {
if (i < size) subp[i].ModMulK1(&subp[i - 1], &ints[i]);
if (i+1 < size) subp[i+1].ModMulK1(&subp[i], &ints[i+1]);
if (i+2 < size) subp[i+2].ModMulK1(&subp[i+1], &ints[i+2]);
if (i+3 < size) subp[i+3].ModMulK1(&subp[i+2], &ints[i+3]);
if (i+4 < size) subp[i+4].ModMulK1(&subp[i+3], &ints[i+4]);
if (i+5 < size) subp[i+5].ModMulK1(&subp[i+4], &ints[i+5]);
if (i+6 < size) subp[i+6].ModMulK1(&subp[i+5], &ints[i+6]);
if (i+7 < size) subp[i+7].ModMulK1(&subp[i+6], &ints[i+7]);
}
} else {
for (int i = 1; i < size; i++) {
subp[i].ModMulK1(&subp[i - 1], &ints[i]);
}
}

// Do the inversion
inverse.Set(&subp[size - 1]);
inverse.ModInv();

for (int i = size - 1; i > 0; i--) {
newValue.ModMulK1(&subp[i - 1], &inverse);
inverse.ModMulK1(&ints[i]);
ints[i].Set(&newValue);
// Unroll the back-substitution loop
if (size >= 8) {
for (int i = size - 1; i > 0; i -= 8) {
if (i >= 8) {
newValue.ModMulK1(&subp[i - 1], &inverse);
inverse.ModMulK1(&ints[i]);
ints[i].Set(&newValue);

newValue.ModMulK1(&subp[i - 2], &inverse);
inverse.ModMulK1(&ints[i-1]);
ints[i-1].Set(&newValue);

newValue.ModMulK1(&subp[i - 3], &inverse);
inverse.ModMulK1(&ints[i-2]);
ints[i-2].Set(&newValue);

newValue.ModMulK1(&subp[i - 4], &inverse);
inverse.ModMulK1(&ints[i-3]);
ints[i-3].Set(&newValue);

newValue.ModMulK1(&subp[i - 5], &inverse);
inverse.ModMulK1(&ints[i-4]);
ints[i-4].Set(&newValue);

newValue.ModMulK1(&subp[i - 6], &inverse);
inverse.ModMulK1(&ints[i-5]);
ints[i-5].Set(&newValue);

newValue.ModMulK1(&subp[i - 7], &inverse);
inverse.ModMulK1(&ints[i-6]);
ints[i-6].Set(&newValue);

newValue.ModMulK1(&subp[i - 8], &inverse);
inverse.ModMulK1(&ints[i-7]);
ints[i-7].Set(&newValue);
}
}
} else {
for (int i = size - 1; i > 0; i--) {
newValue.ModMulK1(&subp[i - 1], &inverse);
inverse.ModMulK1(&ints[i]);
ints[i].Set(&newValue);
}
}

ints[0].Set(&inverse);
Expand Down
5 changes: 1 addition & 4 deletions IntMod.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -909,10 +909,7 @@ void Int::ModMulK1(Int *a, Int *b) {
uint64_t ah, al;
uint64_t t[NB64BLOCK];
#if BISIZE==256
uint64_t r512[8];
r512[5] = 0;
r512[6] = 0;
r512[7] = 0;
uint64_t r512[8] = {0}; // Initialize to zero for better performance
#else
uint64_t r512[12];
r512[5] = 0;
Expand Down
121 changes: 121 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
# ===================================================================
# Pollard-Kangaroo Solver (Mark1) - Optimized Makefile
# ===================================================================

# Compiler and flags
CXX = g++
CXXFLAGS_COMMON = -std=c++17 -march=native -pthread -fopenmp
CXXFLAGS_OPT = -O3 -funroll-loops -ftree-vectorize -fstrict-aliasing \
-fno-semantic-interposition -fvect-cost-model=unlimited \
-fno-trapping-math -fipa-ra -fipa-modref -flto \
-fassociative-math -fomit-frame-pointer -ffast-math \
-malign-data=cacheline -floop-nest-optimize \
-floop-unroll-and-jam -fpeel-loops \
-fvariable-expansion-in-unroller
CXXFLAGS_SIMD = -mavx2 -mbmi2 -madx
CXXFLAGS_DEBUG = -g -O0 -DDEBUG

# Target names
TARGET_MARK1 = Mark1
TARGET_DP_ANALYZER = DP-analyzer

# Source files
SRCS_MARK1 = Mark1.cpp Int.cpp SECP256K1.cpp Point.cpp Random.cpp IntMod.cpp IntGroup.cpp Timer.cpp
SRCS_DP_ANALYZER = DP-analyzer/DP-analyzer.cpp Int.cpp
HDRS = Int.h Point.h SECP256K1.h IntGroup.h Timer.h Random.h hashutil.h simd_block_bloom.h

# Build directories
BUILD_DIR = build
OBJ_DIR = $(BUILD_DIR)/obj
BIN_DIR = $(BUILD_DIR)/bin

# Object files
OBJS_MARK1 = $(OBJ_DIR)/Mark1.o $(OBJ_DIR)/Int.o $(OBJ_DIR)/SECP256K1.o $(OBJ_DIR)/Point.o $(OBJ_DIR)/Random.o $(OBJ_DIR)/IntMod.o $(OBJ_DIR)/IntGroup.o $(OBJ_DIR)/Timer.o
OBJS_DP_ANALYZER = $(OBJ_DIR)/DP-analyzer.o $(OBJ_DIR)/Int.o

# Default target
all: release

# Release build (optimized)
release: CXXFLAGS = $(CXXFLAGS_COMMON) $(CXXFLAGS_OPT) $(CXXFLAGS_SIMD)
release: $(BIN_DIR)/$(TARGET_MARK1) $(BIN_DIR)/$(TARGET_DP_ANALYZER)

# Debug build
debug: CXXFLAGS = $(CXXFLAGS_COMMON) $(CXXFLAGS_DEBUG) $(CXXFLAGS_SIMD)
debug: $(BIN_DIR)/$(TARGET_MARK1)_debug $(BIN_DIR)/$(TARGET_DP_ANALYZER)_debug

# Profile build
profile: CXXFLAGS = $(CXXFLAGS_COMMON) $(CXXFLAGS_OPT) $(CXXFLAGS_SIMD) -pg
profile: $(BIN_DIR)/$(TARGET_MARK1)_profile

# Create directories
$(BUILD_DIR) $(OBJ_DIR) $(BIN_DIR):
mkdir -p $@

# Compile object files (general rule, specific dependencies override)
$(OBJ_DIR)/%.o: %.cpp | $(OBJ_DIR)
$(CXX) $(CXXFLAGS) -c $< -o $@

# Special rule for DP-analyzer in subdirectory
$(OBJ_DIR)/DP-analyzer.o: DP-analyzer/DP-analyzer.cpp | $(OBJ_DIR)
$(CXX) $(CXXFLAGS) -c $< -o $@

# Link Mark1
$(BIN_DIR)/$(TARGET_MARK1): $(OBJS_MARK1) | $(BIN_DIR)
$(CXX) $(CXXFLAGS) $^ -o $@ -fopenmp -pthread

# Link DP-analyzer
$(BIN_DIR)/$(TARGET_DP_ANALYZER): $(OBJS_DP_ANALYZER) | $(BIN_DIR)
$(CXX) $(CXXFLAGS) $^ -o $@

# Debug versions
$(BIN_DIR)/$(TARGET_MARK1)_debug: $(OBJS_MARK1) | $(BIN_DIR)
$(CXX) $(CXXFLAGS) $^ -o $@ -fopenmp -pthread

$(BIN_DIR)/$(TARGET_DP_ANALYZER)_debug: $(OBJS_DP_ANALYZER) | $(BIN_DIR)
$(CXX) $(CXXFLAGS) $^ -o $@

# Profile version
$(BIN_DIR)/$(TARGET_MARK1)_profile: $(OBJS_MARK1) | $(BIN_DIR)
$(CXX) $(CXXFLAGS) $^ -o $@ -fopenmp -pthread -pg

# Clean
clean:
rm -rf $(BUILD_DIR)

# Deep clean (removes DP table files too)
distclean: clean
rm -f dp_table.bin DP.bin

# Dependencies
$(OBJ_DIR)/Mark1.o: Mark1.cpp Int.h Point.h SECP256K1.h IntGroup.h Timer.h Random.h hashutil.h simd_block_bloom.h
$(OBJ_DIR)/Int.o: Int.cpp Int.h
$(OBJ_DIR)/SECP256K1.o: SECP256K1.cpp SECP256K1.h Int.h Point.h
$(OBJ_DIR)/Point.o: Point.cpp Point.h Int.h
$(OBJ_DIR)/Random.o: Random.cpp Random.h
$(OBJ_DIR)/IntMod.o: IntMod.cpp Int.h
$(OBJ_DIR)/IntGroup.o: IntGroup.cpp IntGroup.h Int.h
$(OBJ_DIR)/Timer.o: Timer.cpp Timer.h
$(OBJ_DIR)/DP-analyzer.o: DP-analyzer/DP-analyzer.cpp Int.h

# Help
help:
@echo "Pollard-Kangaroo Solver (Mark1) - Makefile"
@echo ""
@echo "Targets:"
@echo " all - Build optimized release version (default)"
@echo " release - Build optimized release version"
@echo " debug - Build debug version with symbols"
@echo " profile - Build with profiling support"
@echo " clean - Remove build artifacts"
@echo " distclean - Remove build artifacts and data files"
@echo " help - Show this help"
@echo ""
@echo "Executables will be placed in $(BIN_DIR)/"
@echo ""
@echo "Usage examples:"
@echo " make release # Build optimized version"
@echo " make debug # Build debug version"
@echo " ./build/bin/Mark1 --help"

.PHONY: all release debug profile clean distclean help
Binary file added Mark1
Binary file not shown.
Loading