forked from Qortal/qortal
Fix incorrect PoW buffer length usage
This commit is contained in:
parent
758a42db36
commit
847093edac
@ -2,85 +2,8 @@ package org.qortal.crypto;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import com.google.common.primitives.Bytes;
|
||||
|
||||
public class MemoryPoW {
|
||||
|
||||
private static final int HASH_LENGTH = 32;
|
||||
private static final int HASH_LENGTH_MASK = HASH_LENGTH - 1;
|
||||
|
||||
public static Integer compute(byte[] data, int workBufferLength, int start, int range, int difficulty) {
|
||||
if (range < 1)
|
||||
throw new IllegalArgumentException("range must be at least 1");
|
||||
|
||||
if (difficulty < 1)
|
||||
throw new IllegalArgumentException("difficulty must be at least 1");
|
||||
|
||||
final int workBufferLengthMask = workBufferLength - 1;
|
||||
|
||||
// Hash data with SHA256
|
||||
byte[] hash = Crypto.digest(data);
|
||||
|
||||
assert hash.length == HASH_LENGTH;
|
||||
|
||||
byte[] perturbedHash = new byte[HASH_LENGTH];
|
||||
byte[] workBuffer = new byte[workBufferLength];
|
||||
byte[] bufferHash = new byte[HASH_LENGTH];
|
||||
|
||||
// For each nonce...
|
||||
for (int nonce = start; nonce < start + range; ++nonce) {
|
||||
// Perturb hash using nonce
|
||||
int temp = nonce;
|
||||
for (int hi = 0; hi < HASH_LENGTH; ++hi) {
|
||||
perturbedHash[hi] = (byte) (hash[hi] ^ (temp & 0xff));
|
||||
temp >>>= 1;
|
||||
}
|
||||
|
||||
// Fill large working memory buffer using hash, further perturbing as we go
|
||||
int wanderingBufferOffset = 0;
|
||||
byte ch = 0;
|
||||
|
||||
int hashOffset = 0;
|
||||
|
||||
for (int workBufferOffset = 0; workBufferOffset < workBufferLength; workBufferOffset += HASH_LENGTH) {
|
||||
System.arraycopy(perturbedHash, 0, workBuffer, workBufferOffset, HASH_LENGTH);
|
||||
|
||||
hashOffset = ++hashOffset & HASH_LENGTH_MASK;
|
||||
|
||||
ch += perturbedHash[hashOffset];
|
||||
|
||||
for (byte hi = 0; hi < HASH_LENGTH; ++hi) {
|
||||
byte hashByte = perturbedHash[hi];
|
||||
wanderingBufferOffset = (wanderingBufferOffset << 3) ^ (hashByte & 0xff);
|
||||
|
||||
perturbedHash[hi] = (byte) (hashByte ^ (ch + hi));
|
||||
}
|
||||
|
||||
workBuffer[wanderingBufferOffset & workBufferLengthMask] ^= 0xAA;
|
||||
|
||||
// final int finalWanderingBufferOffset = wanderingBufferOffset & WORK_BUFFER_LENGTH_MASK;
|
||||
// System.out.println(String.format("wanderingBufferOffset: 0x%08x / 0x%08x - %02d%%", finalWanderingBufferOffset, WORK_BUFFER_LENGTH, finalWanderingBufferOffset * 100 / WORK_BUFFER_LENGTH));
|
||||
}
|
||||
|
||||
Bytes.reverse(workBuffer);
|
||||
|
||||
// bufferHash = Crypto.digest(workBuffer);
|
||||
System.arraycopy(workBuffer, 0, bufferHash, 0, HASH_LENGTH);
|
||||
|
||||
int hi = 0;
|
||||
for (hi = 0; hi < difficulty; ++hi)
|
||||
if (bufferHash[hi] != 0)
|
||||
break;
|
||||
|
||||
if (hi == difficulty)
|
||||
return nonce;
|
||||
|
||||
Thread.yield();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Integer compute2(byte[] data, int workBufferLength, long difficulty) {
|
||||
// Hash data with SHA256
|
||||
byte[] hash = Crypto.digest(data);
|
||||
@ -94,7 +17,7 @@ public class MemoryPoW {
|
||||
byteBuffer = null;
|
||||
|
||||
int longBufferLength = workBufferLength / 8;
|
||||
long[] workBuffer = new long[longBufferLength / 8];
|
||||
long[] workBuffer = new long[longBufferLength];
|
||||
long[] state = new long[4];
|
||||
|
||||
long seed = 8682522807148012L;
|
||||
|
@ -4,7 +4,6 @@
|
||||
typedef unsigned long long uint64_t;
|
||||
#endif
|
||||
|
||||
#define WORKBUFFER_LENGTH (longBufferLength / 8)
|
||||
#define INTEGER_MAX_VALUE 0x7fffffffULL
|
||||
|
||||
uint64_t xoshiro256p(uint64_t state[]) {
|
||||
@ -71,13 +70,13 @@ uint32_t compute2(uint8_t *hash, uint64_t *workBuffer, uint32_t workBufferLength
|
||||
state[3] = longHash[3] ^ seed;
|
||||
|
||||
// Fill work buffer with random
|
||||
for (uint32_t i = 0; i < WORKBUFFER_LENGTH; ++i)
|
||||
for (uint32_t i = 0; i < longBufferLength; ++i)
|
||||
workBuffer[i] = xoshiro256p(state);
|
||||
|
||||
// Random bounce through whole buffer
|
||||
result = workBuffer[0];
|
||||
for (uint32_t i = 0; i < 1024; ++i) {
|
||||
uint32_t index = (uint32_t) (xoshiro256p(state) & INTEGER_MAX_VALUE) % WORKBUFFER_LENGTH;
|
||||
uint32_t index = (uint32_t) (xoshiro256p(state) & INTEGER_MAX_VALUE) % longBufferLength;
|
||||
result ^= workBuffer[index];
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user