Some more POW work - it seems to work, but is very, very, extremely slow.
This commit is contained in:
parent
daa9a9911b
commit
751ed0c637
@ -43,9 +43,24 @@ public class Bytes {
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean lt(byte[] a, byte[] b, int size) {
|
||||
for (int i = 0; i < size; i++) {
|
||||
if (a[i] != b[i]) {
|
||||
return lt(a[i], b[i]);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean lt(byte a, byte b) {
|
||||
if (a < 0) return b < 0 && a < b;
|
||||
if (b < 0) return a >= 0 || a < b;
|
||||
return a < b;
|
||||
}
|
||||
|
||||
public static byte[] expand(byte[] source, int size) {
|
||||
byte[] result = new byte[size];
|
||||
System.arraycopy(source, 0, result, size - source.length, source.length);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
@ -18,11 +18,14 @@ package ch.dissem.bitmessage.utils;
|
||||
|
||||
import ch.dissem.bitmessage.entity.ObjectMessage;
|
||||
import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.math.BigInteger;
|
||||
import java.security.GeneralSecurityException;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.SecureRandom;
|
||||
|
||||
import static ch.dissem.bitmessage.utils.Bytes.inc;
|
||||
@ -31,6 +34,7 @@ import static ch.dissem.bitmessage.utils.Bytes.inc;
|
||||
* Provides some methods to help with hashing and encryption.
|
||||
*/
|
||||
public class Security {
|
||||
public static final Logger LOG = LoggerFactory.getLogger(Security.class);
|
||||
private static final SecureRandom RANDOM = new SecureRandom();
|
||||
private static final BigInteger TWO = BigInteger.valueOf(2);
|
||||
|
||||
@ -73,24 +77,26 @@ public class Security {
|
||||
byte[] initialHash = getInitialHash(object);
|
||||
|
||||
byte[] target = getProofOfWorkTarget(object, nonceTrialsPerByte, extraBytes);
|
||||
// start with trialValue = 99999999999999999999
|
||||
byte[] trialValue;
|
||||
if (target.length < 8) {
|
||||
target = Bytes.expand(target, 8);
|
||||
}
|
||||
// also start with nonce = 0 where nonce is 8 bytes in length and can be hashed as if it is a string.
|
||||
byte[] nonce = new byte[8];
|
||||
MessageDigest mda = md("SHA-512");
|
||||
MessageDigest mda = null;
|
||||
try {
|
||||
mda = MessageDigest.getInstance("SHA-512");
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
do {
|
||||
inc(nonce);
|
||||
mda.update(nonce);
|
||||
mda.update(initialHash);
|
||||
trialValue = bytes(mda.digest(mda.digest()), 8);
|
||||
} while (Bytes.lt(target, trialValue));
|
||||
} while (Bytes.lt(target, mda.digest(mda.digest()), 8));
|
||||
object.setNonce(nonce);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param object
|
||||
* @param nonceTrialsPerByte
|
||||
* @param extraBytes
|
||||
* @throws IOException if proof of work doesn't check out
|
||||
*/
|
||||
public static void checkProofOfWork(ObjectMessage object, long nonceTrialsPerByte, long extraBytes) throws IOException {
|
||||
@ -113,6 +119,7 @@ public class Security {
|
||||
|
||||
private static byte[] getProofOfWorkTarget(ObjectMessage object, long nonceTrialsPerByte, long extraBytes) throws IOException {
|
||||
BigInteger TTL = BigInteger.valueOf(object.getExpiresTime() - (System.currentTimeMillis() / 1000));
|
||||
LOG.debug("TTL: " + TTL + "s");
|
||||
BigInteger numerator = TWO.pow(64);
|
||||
BigInteger powLength = BigInteger.valueOf(object.getPayloadBytes().length + extraBytes);
|
||||
BigInteger denominator = BigInteger.valueOf(nonceTrialsPerByte).multiply(powLength.add(powLength.multiply(TTL).divide(BigInteger.valueOf(2).pow(16))));
|
||||
|
@ -50,4 +50,18 @@ public class BytesTest {
|
||||
assertEquals(a.compareTo(b) == -1, Bytes.lt(a.toByteArray(), b.toByteArray()));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLowerThanBounded() {
|
||||
Random rnd = new Random();
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
BigInteger a = BigInteger.valueOf(rnd.nextLong()).pow((rnd.nextInt(5) + 1)).abs();
|
||||
BigInteger b = BigInteger.valueOf(rnd.nextLong()).pow((rnd.nextInt(5) + 1)).abs();
|
||||
System.out.println("a = " + a.toString(16) + "\tb = " + b.toString(16));
|
||||
assertEquals(a.compareTo(b) == -1, Bytes.lt(
|
||||
Bytes.expand(a.toByteArray(), 100),
|
||||
Bytes.expand(b.toByteArray(), 100),
|
||||
100));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user