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;
|
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) {
|
private static boolean lt(byte a, byte b) {
|
||||||
if (a < 0) return b < 0 && a < b;
|
if (a < 0) return b < 0 && a < b;
|
||||||
if (b < 0) return a >= 0 || a < b;
|
if (b < 0) return a >= 0 || a < b;
|
||||||
return 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 ch.dissem.bitmessage.entity.ObjectMessage;
|
||||||
import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
import java.security.GeneralSecurityException;
|
import java.security.GeneralSecurityException;
|
||||||
import java.security.MessageDigest;
|
import java.security.MessageDigest;
|
||||||
|
import java.security.NoSuchAlgorithmException;
|
||||||
import java.security.SecureRandom;
|
import java.security.SecureRandom;
|
||||||
|
|
||||||
import static ch.dissem.bitmessage.utils.Bytes.inc;
|
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.
|
* Provides some methods to help with hashing and encryption.
|
||||||
*/
|
*/
|
||||||
public class Security {
|
public class Security {
|
||||||
|
public static final Logger LOG = LoggerFactory.getLogger(Security.class);
|
||||||
private static final SecureRandom RANDOM = new SecureRandom();
|
private static final SecureRandom RANDOM = new SecureRandom();
|
||||||
private static final BigInteger TWO = BigInteger.valueOf(2);
|
private static final BigInteger TWO = BigInteger.valueOf(2);
|
||||||
|
|
||||||
@ -73,24 +77,26 @@ public class Security {
|
|||||||
byte[] initialHash = getInitialHash(object);
|
byte[] initialHash = getInitialHash(object);
|
||||||
|
|
||||||
byte[] target = getProofOfWorkTarget(object, nonceTrialsPerByte, extraBytes);
|
byte[] target = getProofOfWorkTarget(object, nonceTrialsPerByte, extraBytes);
|
||||||
// start with trialValue = 99999999999999999999
|
if (target.length < 8) {
|
||||||
byte[] trialValue;
|
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.
|
// 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];
|
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 {
|
do {
|
||||||
inc(nonce);
|
inc(nonce);
|
||||||
mda.update(nonce);
|
mda.update(nonce);
|
||||||
mda.update(initialHash);
|
mda.update(initialHash);
|
||||||
trialValue = bytes(mda.digest(mda.digest()), 8);
|
} while (Bytes.lt(target, mda.digest(mda.digest()), 8));
|
||||||
} while (Bytes.lt(target, trialValue));
|
|
||||||
object.setNonce(nonce);
|
object.setNonce(nonce);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param object
|
|
||||||
* @param nonceTrialsPerByte
|
|
||||||
* @param extraBytes
|
|
||||||
* @throws IOException if proof of work doesn't check out
|
* @throws IOException if proof of work doesn't check out
|
||||||
*/
|
*/
|
||||||
public static void checkProofOfWork(ObjectMessage object, long nonceTrialsPerByte, long extraBytes) throws IOException {
|
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 {
|
private static byte[] getProofOfWorkTarget(ObjectMessage object, long nonceTrialsPerByte, long extraBytes) throws IOException {
|
||||||
BigInteger TTL = BigInteger.valueOf(object.getExpiresTime() - (System.currentTimeMillis() / 1000));
|
BigInteger TTL = BigInteger.valueOf(object.getExpiresTime() - (System.currentTimeMillis() / 1000));
|
||||||
|
LOG.debug("TTL: " + TTL + "s");
|
||||||
BigInteger numerator = TWO.pow(64);
|
BigInteger numerator = TWO.pow(64);
|
||||||
BigInteger powLength = BigInteger.valueOf(object.getPayloadBytes().length + extraBytes);
|
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))));
|
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()));
|
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