[Cyclone] docs | 主程序逻辑 | 地址解码器 | P2PKH地址

"If you want to do extraordinary things, it shouldn't be easy".

链接:https://github.com/Dookoo2/Cyclone

docs:Cyclone

Cyclone 是一款多线程应用程序,专为搜索特定比特币地址对应的私钥而设计。

该工具通过*椭圆曲线密码学(ECC)和高度优化的*哈希算法,高效计算大范围私钥对应的公钥

并利用现代CPU的*SIMD指令集*实现加速运算。

前文:直观理解ECC椭圆曲线加密算法

架构

章节导航

  1. 主程序逻辑(Cyclone.cpp)
  2. 地址解码器(P2PKHDecoder)
  3. 哈希算法(SHA-256/RIPEMD-160)
  4. SIMD优化哈希(AVX2/AVX512)
  5. 大数运算(Int类)
  6. 椭圆曲线点运算(Point类)
  7. Secp256k1操作(SECP256K1模块)
  8. 批量模逆运算(IntGroup类)

第一章:主程序逻辑(Cyclone.cpp)

欢迎来到Cyclone的首个章节!

本章将深入解析项目的核心组件------Cyclone.cpp文件。该文件作为整个系统的"控制中枢",负责程序初始化、指令解析、资源配置以及比特币私钥搜索的全流程管理

核心目标:大海捞针

假设我们持有特定比特币地址(如著名地址1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa),该地址由唯一私钥生成。我们的挑战在于从海量可能中定位这个私钥,这如同在万亿级坐标系中寻找特定地址的精确秘钥。

Cyclone正是为此设计,而Cyclone.cpp则是实现这一搜索的核心调度模块。

典型应用场景为在指定私钥范围内进行搜索。本章重点解析该模块如何实现这一核心任务。

运行Cyclone程序

在深入代码前,我们先了解实际运行Cyclone进行私钥搜索的操作方法。通过命令行参数指定目标地址和搜索范围:

bash 复制代码
./Cyclone -a <目标比特币地址> -r <起始私钥HEX>:<结束私钥HEX>

参数解析:

  • ./Cyclone:可执行程序路径(需根据编译位置调整)
  • -a:指定目标比特币地址(如1KbATWphoKptFp4g79L1n87n5o726LqD49
  • -r:定义私钥搜索范围的十六进制起止值(示例:-r 100000000000000000000000000000000:200000000000000000000000000000000

执行后,Cyclone将遍历指定范围的私钥,计算对应地址并与目标匹配。若发现匹配项,将立即输出私钥信息。

Cyclone.cpp核心流程

Cyclone.cpp的核心工作流程分为八个阶段:

  1. 指令解析:读取命令行参数中的地址和搜索范围
  2. 目标预处理:将比特币地址转换为20字节哈希格式
  3. 任务划分 :根据CPU核心数分割搜索范围
  4. 线程初始化 :启动多线程工作单元
  5. 并行搜索各线程独立处理分配的子范围
  6. 进度监控:定期汇总并展示搜索状态
  7. 断点续查 :保存当前搜索位置支持中断恢复
  8. 结果处理:发现匹配时终止搜索并输出密钥

main()函数架构

C++程序的入口函数main()负责整体流程控制,其简化结构如下:

c++ 复制代码
int main(int argc, char* argv[]) {
    // 阶段1:解析命令行参数
    // 阶段2:参数校验与初始化
    // 阶段3:计算线程数量
    // 阶段4:划分搜索范围
    // 阶段5:初始化统计计时器
    // 阶段6:启动并行搜索
    #pragma omp parallel num_threads(numCPUs) {
        // 核心搜索循环
    }
    // 阶段7:输出最终结果
    return 0;
}
参数解析实现

通过遍历argv数组识别参数标记:

c++ 复制代码
for(int i=1;i<argc;++i){
    if(!strcmp(argv[i],"-a") && i+1<argc){
        targetAddress = argv[++i];
        targetHash160 = P2PKHDecoder::getHash160(targetAddress);
    }
    // 其他参数处理...
}

该代码段调用地址解码器将比特币地址转换为20字节哈希,便于后续快速比对。

范围划分算法

使用大数运算处理十六进制范围值:

c++ 复制代码
auto startBN = hexToBigNum(startHex);
auto endBN = hexToBigNum(endHex);
auto rangeSize = bigNumSubtract(endBN, startBN);
auto [chunk, remainder] = bigNumDivide(rangeSize, numCPUs);

for(int t=0; t<numCPUs; ++t){
    // 分配各线程起止范围
}

该算法将总范围均分给每个线程,处理超大数时采用定制的大数运算库。

并行搜索机制

通过OpenMP实现多线程并行计算,每个线程独立处理分配的子范围:

c++ 复制代码
#pragma omp parallel num_threads(numCPUs)
{
    int tid = omp_get_thread_num();
    Int priv = hexToInt(threadRanges[tid].startHex);
    
    while(!matchFound) {
        // 批量生成公钥
        // SIMD加速哈希计算
        // 结果比对
        // 状态更新
    }
}

核心计算流程

每个线程的执行周期包含五个关键步骤:

批量公钥生成优化

采用椭圆曲线点加法的数学特性实现高效批量计算

c++ 复制代码
Point base = secp.ComputePublicKey(&priv);
for(int i=0; i<512; ++i){
    // 基于基准点计算偏移公钥
}

该方法相比单点计算效率提升约40倍,具体实现依赖批量模逆运算模块

SIMD哈希加速

使用AVX512指令集并行处理16个哈希计算:

c++ 复制代码
computeHash160BatchBinSingle(16, pubKeys, hashRes);
for(int j=0; j<16; ++j){
    if(memcmp(hashRes[j], targetHash160, 20) == 0){
        // 触发匹配处理
    }
}

该优化使哈希计算吞吐量提升15倍以上,详见SIMD哈希优化章节

状态监控与恢复

主线程定期收集各工作线程状态:

c++ 复制代码
#pragma omp critical {
    globalChecked += localChecked;
    mkeys = globalChecked / elapsed / 1e6;
    printStats(...);
}

断点保存机制将当前搜索位置写入progress.txt,支持中断后从最后位置继续搜索。

匹配处理流程

当线程检测到哈希匹配时:

c++ 复制代码
#pragma omp critical(full_match) {
    if(!matchFound) {
        matchFound = true;
        // 计算WIF格式私钥
    }
}
#pragma omp cancel parallel

临界区确保仅一个线程处理匹配结果,并立即终止所有工作线程。

架构总结

Cyclone.cpp作为核心调度模块,实现了:

  • 多线程任务分配与负载均衡
  • 大规模并行计算优化
  • 实时状态监控与交互
  • 安全可靠的断点续查
  • 高效资源管理机制

下一章将深入解析地址解码器(P2PKHDecoder)的工作原理。


第二章:地址解码器(P2PKHDecoder)

在上一章主程序逻辑(Cyclone.cpp)中,我们了解了Cyclone.cpp如何作为指挥中枢,将我们提供的比特币地址和搜索范围转化为高效的私钥搜索流程。

本章将聚焦于整个流程的起点------地址解码器P2PKHDecoder组件)。该模块承担着将人类可读的比特币地址转换为计算机可处理的20字节哈希值(Hash160)的核心任务。

P2PKH地址解析

地址结构解析

P2PKH(Pay to Public Key Hash)地址是比特币网络中最基础的地址类型,其结构特征如下

  • 版本标识 :首字节为0x00,对应地址首字符为'1'
  • 哈希主体 :20字节的RIPEMD160(SHA256(公钥))计算结果
  • 校验码:4字节的校验序列,基于版本标识和哈希主体生成

地址设计前文:
[Linux_69] 数据链路层 | Mac帧格式 | 局域网转发 | MTU & MSS

例如网络部分,Mac帧当中也设有CRC校验码

核心转换流程

地址解码器需要完成以下关键转换步骤

  1. Base58解码 :将人类可读字符串转化为25字节二进制数据
  2. 校验验证 :通过双重SHA256计算验证数据完整性
  3. 哈希提取:剥离版本标识与校验码,获取20字节哈希核心
c++ 复制代码
// 代码片段:主程序调用解码器
std::vector<uint8_t> targetHash160 = P2PKHDecoder::getHash160(targetAddress);

技术实现细节

Base58解码算法

比特币采用定制化Base58编码方案,规避易混淆字符(0/O, I/l等)。其解码过程包含:

字符映射表

c++ 复制代码
const std::string BASE58_ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";

解码流程

c++ 复制代码
std::vector<uint8_t> base58_decode(const std::string& input) {
    std::vector<uint8_t> bytes;
    // 初始化零值字节处理
    for (char c : input) {
        size_t index = BASE58_ALPHABET.find(c);
        // 多项式乘法转换基数
        for (size_t i=0; i<bytes.size(); ++i) {
            carry += 58 * bytes[i];
            bytes[i] = carry & 0xFF;
            carry >>= 8;
        }
        // 处理进位溢出
    }
    // 前导'1'字符处理
    // 字节序调整
    return bytes;
}

校验码验证机制

采用双重SHA256哈希验证数据完整性

c++ 复制代码
std::vector<uint8_t> data = get_header_and_hash(decoded); // 获取前21字节
std::vector<uint8_t> hash1 = sha256(data); 
std::vector<uint8_t> hash2 = sha256(hash1);
std::vector<uint8_t> computed_checksum = get_first_4bytes(hash2);

WIF私钥编码

发现有效私钥时,采用Wallet Import Format编码输出

c++ 复制代码
std::string compute_wif(const std::string& privKeyHex, bool compressed) {
    // 添加版本标识0x80
    // 压缩标识处理
    // 双重SHA256生成校验码
    return base58_encode(final_bytes);
}

架构类比说明

可将地址解码器比作密码本翻译官:

  • Base58字符串:经过加密的密文消息
  • 版本标识:密码本版本标识符
  • 校验码:防篡改封印
  • 哈希核心:解密后的情报内容

关键技术点

  1. 可变长度处理动态调整前导零字节数量,准确还原原始二进制数据
  2. 大数运算优化 :采用多项式乘法实现高效基数转换
  3. 错误容忍机制:通过字符白名单检测和长度验证预防非法输入
  4. 并行计算兼容:无状态函数设计支持多线程调用

应用扩展

该解码器技术可延伸应用于:

  • 区块链浏览器开发:实现地址有效性验证
  • 钱包软件集成:支持多种地址格式解析
  • 交易监控系统:实时解析链上交易数据

下一章将深入解析哈希算法(SHA-256/RIPEMD-160),揭示Hash160的生成机制。