概述
要求N次(轮)迭代下散列计算一个nonce
每轮从16个著名算法中选择一个随机散列算法
第x轮的输入值用所有先前轮的输出加盐
第x轮是输入是一个先前、临近轮的输出的压缩,大小100bytes
每轮输出是扩充,为了实现内存难度
随机性使用Mersenne Twister算法生成
随机性是通过每轮MurMur3校验和来播种
最终轮然后会被Sha2_256重新散列计算,来保持传统加密货币的方式
图
一点都不简单明了
伪代码分析
首先定义N为5 (那么总共的参与计算的轮数即为2^5 - 1 = 31
M(内存膨胀单元)为10KB
在第一轮:
先对区块头进行校验和计算出seed【1】
通过seed生成随机数【2】
设置roundInput为区块头
获得gen的下一个双字节值除18取余的余数,取出hash_algo列表中对应下标的散列计算方式。
用取出的散列计算方式计算roundInput获得输出值
将输出值通过 N-轮数 扩展内存难度。()
将最终输出值添加进roundOutputs这个数组中
返回这个roundOutput数组
在其他轮(2-N):
- 先设置父输出值为之前轮RandomHash结果(利用这个进行迭代)
- 设置seed为上个RandomHash输出的校验和
- 通过seed获得一个随机数
- 将所有的之前的输出值都放入roundOutputs数组之中
- 再使用ChangeNonce【3】对区块头换个nonce
- 对新的区块头,设置邻近输出值为对其的前几轮RandomHash结果
- 将这些也加入roundOutput数组中
- 将roundOutput进行压缩获得roundInput
重复上面4-8
计算细节:
【1】校验和计算:标准MurMu3算法 (可计算一个字符数组或者字符数组的数组)
【2】随机数生成:标准的Mersenne Twister(梅森旋转演算法)随机数生成
【3】改变nonce:克隆并修改区块头中的nonce值。(通过确定nonce的位偏移)
【4】压缩:输入为一个Byte数组的列表
- 对input进行校验和计算,
- 对计算结果进行随机数生成
- (强制)定义输出为一个100长度的Byte
- 循环100(i = 0-99)次,每次先设source为输入值中“第随机数除输入值长度的取余”个。然后输出值中第i个即为source中第“随机数除source长度取余”个。最终得到一个100长度的结果
【5】扩展:输入为一个Byte的数组 以及一个整数作为扩展因数 - 对input进行校验和计算
- 对计算结果进行随机数生成
- size为输入的长度+ M×扩展因数,M为10KB
- 输出为输入的克隆
- 设置将加入的bytes个数为size-输入长度
- 当将加入的bytes个数>0时,设 下一数据块为输出的clone 如果
下一数据块长度比将加入的bytes个数大那么将下一数据块长度重新设置为将加入的bytes个数。然后对随机数除8取余 额……++不知道是什么操作……大概是次方?
反正对应8种操作:
- 不操作 (e.g. input = 123456 output = 123456)
- 不乱序,中间交换前后 (e.g. input = 123456 output = 456123)
- 反转 (e.g. input = 123456 output = 654321)
- 左交错 (e.g. input = 123456 output = 142536)
- 右交错 (e.g. input = 123456 output = 415263)
- 左亦或 (e.g. input = 123456 output = XOR(1,2), XOR(3,4), XOR(5,6), XOR(1,6), XOR(2,5), XOR(3,4)
- ROL递增 (e.g. input = ABCDEF output = ROL(A, 0), ROL(B, 1), ... , ROL(F, 5)
- ROR递增 (e.g. input = ABCDEF output = ROR(A, 0), ROR(B, 1), ... , ROR(F, 5)
TESTNET挖矿软件源码分析
基于TESTNET v3.1
文件:pascalcoin_miner.pp
首先这个挖矿软件的GPU部分是基于cl的,不照顾cuda。
CPU挖矿:TCPUDeviceThread.Create (src/core/UPoolMinerThreads.pas)
GPU挖矿:TGPUDeviceThread.Create (src/core/UGPUMining.pas)
主要目标是GPU