From 388a10fe8ae7a98707d0454b3f8d9d70dea4b8b5 Mon Sep 17 00:00:00 2001 From: Christian Basler Date: Tue, 14 Apr 2015 21:52:21 +0200 Subject: [PATCH] Moved POW to its own port so it will be easily possible to create other (faster) implementations --- .../bitmessage/ports/ProofOfWorkEngine.java | 34 ++++++++++++++ .../bitmessage/ports/SimplePOWEngine.java | 46 +++++++++++++++++++ .../ch/dissem/bitmessage/utils/Security.java | 21 ++------- .../dissem/bitmessage/utils/SecurityTest.java | 13 +++++- 4 files changed, 95 insertions(+), 19 deletions(-) create mode 100644 domain/src/main/java/ch/dissem/bitmessage/ports/ProofOfWorkEngine.java create mode 100644 domain/src/main/java/ch/dissem/bitmessage/ports/SimplePOWEngine.java diff --git a/domain/src/main/java/ch/dissem/bitmessage/ports/ProofOfWorkEngine.java b/domain/src/main/java/ch/dissem/bitmessage/ports/ProofOfWorkEngine.java new file mode 100644 index 0000000..0c14a86 --- /dev/null +++ b/domain/src/main/java/ch/dissem/bitmessage/ports/ProofOfWorkEngine.java @@ -0,0 +1,34 @@ +/* + * Copyright 2015 Christian Basler + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ch.dissem.bitmessage.ports; + +/** + * Does the proof of work necessary to send an object. + */ +public interface ProofOfWorkEngine { + /** + * Returns a nonce, such that the first 8 bytes from sha512(sha512(nonce||initialHash)) represent a unsigned long + * smaller than target. + * + * @param initialHash the SHA-512 hash of the object to send, sans nonce + * @param target the target, representing an unsigned long + * @param nonceTrialsPerByte + * @param extraBytes + * @return 8 bytes nonce + */ + byte[] calculateNonce(byte[] initialHash, byte[] target, long nonceTrialsPerByte, long extraBytes); +} diff --git a/domain/src/main/java/ch/dissem/bitmessage/ports/SimplePOWEngine.java b/domain/src/main/java/ch/dissem/bitmessage/ports/SimplePOWEngine.java new file mode 100644 index 0000000..85edb27 --- /dev/null +++ b/domain/src/main/java/ch/dissem/bitmessage/ports/SimplePOWEngine.java @@ -0,0 +1,46 @@ +/* + * Copyright 2015 Christian Basler + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ch.dissem.bitmessage.ports; + +import ch.dissem.bitmessage.utils.Bytes; + +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; + +import static ch.dissem.bitmessage.utils.Bytes.inc; + +/** + * Created by chris on 14.04.15. + */ +public class SimplePOWEngine implements ProofOfWorkEngine { + @Override + public byte[] calculateNonce(byte[] initialHash, byte[] target, long nonceTrialsPerByte, long extraBytes) { + byte[] nonce = new byte[8]; + MessageDigest mda; + try { + mda = MessageDigest.getInstance("SHA-512"); + } catch (NoSuchAlgorithmException e) { + throw new RuntimeException(e); + } + do { + inc(nonce); + mda.update(nonce); + mda.update(initialHash); + } while (Bytes.lt(target, mda.digest(mda.digest()), 8)); + return nonce; + } +} diff --git a/domain/src/main/java/ch/dissem/bitmessage/utils/Security.java b/domain/src/main/java/ch/dissem/bitmessage/utils/Security.java index 30cfef3..556ebc9 100644 --- a/domain/src/main/java/ch/dissem/bitmessage/utils/Security.java +++ b/domain/src/main/java/ch/dissem/bitmessage/utils/Security.java @@ -17,6 +17,7 @@ package ch.dissem.bitmessage.utils; import ch.dissem.bitmessage.entity.ObjectMessage; +import ch.dissem.bitmessage.ports.ProofOfWorkEngine; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -25,11 +26,8 @@ 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; - /** * Provides some methods to help with hashing and encryption. */ @@ -68,23 +66,12 @@ public class Security { return result; } - public static void doProofOfWork(ObjectMessage object, long nonceTrialsPerByte, long extraBytes) throws IOException { + public static void doProofOfWork(ObjectMessage object, ProofOfWorkEngine worker, long nonceTrialsPerByte, long extraBytes) throws IOException { byte[] initialHash = getInitialHash(object); byte[] target = getProofOfWorkTarget(object, nonceTrialsPerByte, extraBytes); - // 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; - try { - mda = MessageDigest.getInstance("SHA-512"); - } catch (NoSuchAlgorithmException e) { - throw new RuntimeException(e); - } - do { - inc(nonce); - mda.update(nonce); - mda.update(initialHash); - } while (Bytes.lt(target, mda.digest(mda.digest()), 8)); + + byte[] nonce = worker.calculateNonce(initialHash, target, nonceTrialsPerByte, extraBytes); object.setNonce(nonce); } diff --git a/domain/src/test/java/ch/dissem/bitmessage/utils/SecurityTest.java b/domain/src/test/java/ch/dissem/bitmessage/utils/SecurityTest.java index 79862bc..756017c 100644 --- a/domain/src/test/java/ch/dissem/bitmessage/utils/SecurityTest.java +++ b/domain/src/test/java/ch/dissem/bitmessage/utils/SecurityTest.java @@ -18,10 +18,12 @@ package ch.dissem.bitmessage.utils; import ch.dissem.bitmessage.entity.ObjectMessage; import ch.dissem.bitmessage.entity.payload.GenericPayload; +import ch.dissem.bitmessage.ports.SimplePOWEngine; import org.junit.Test; import javax.xml.bind.DatatypeConverter; import java.io.IOException; +import java.security.KeyPairGenerator; import java.util.Calendar; import java.util.GregorianCalendar; @@ -84,7 +86,14 @@ public class SecurityTest { .expiresTime(expires.getTimeInMillis() / 1000) .payload(new GenericPayload(1, new byte[0])) .build(); - Security.doProofOfWork(objectMessage, 1000, 1000); - Security.checkProofOfWork(objectMessage, 1000, 1000); + Security.doProofOfWork(objectMessage, new SimplePOWEngine(), 10, 10); + Security.checkProofOfWork(objectMessage, 10, 10); + } + + @Test + public void testECIES() throws Exception { + KeyPairGenerator kpg = KeyPairGenerator.getInstance("ECIES", "BC"); +// kpg.initialize(); + kpg.generateKeyPair(); } }