From d75060e9149b639c31935c3d9c50ee087a7e858e Mon Sep 17 00:00:00 2001 From: Tal Moran Date: Mon, 9 Nov 2015 14:21:22 +0200 Subject: [PATCH] Actually added digest implementation (and minor change to interface) --- src/main/java/meerkat/crypto/Digest.java | 40 +++++++++++ .../meerkat/crypto/concrete/SHA256Digest.java | 67 ++++++++++++++++++- 2 files changed, 106 insertions(+), 1 deletion(-) diff --git a/src/main/java/meerkat/crypto/Digest.java b/src/main/java/meerkat/crypto/Digest.java index 1de1e28..a715b26 100644 --- a/src/main/java/meerkat/crypto/Digest.java +++ b/src/main/java/meerkat/crypto/Digest.java @@ -1,7 +1,47 @@ package meerkat.crypto; +import com.google.protobuf.Message; + +import java.security.MessageDigest; + /** * Created by talm on 11/9/15. */ public interface Digest { + + /** + * Marker between messages + */ + public static final byte[] CONCAT_MARKER = {(byte) 0xde, (byte) 0xad, (byte) 0xbe, (byte) 0xef, + (byte) 0xba, (byte) 0x1d, (byte) 0xfa, (byte) 0xce}; + + /** + * Completes the hash computation by performing final operations such as padding. + * (copied from {@link MessageDigest#digest()}) + * @return + */ + byte[] digest(); + + /** + * Updates the digest using the specified message (in serialized wire form) + * + * Includes a special message concatenation marker (the 64 bit message {@link #CONCAT_MARKER}) in the digest (digesting a single message + * will give a different result than the same message split into two messages). + * Messages must not contain the {@link #CONCAT_MARKER}) marker. + * @param msg + * @return + */ + void update(Message msg); + + /** + * Resets the digest for further use. + */ + void reset(); + + /** + * Clone the current digest state + * @return + */ + public Digest clone() throws CloneNotSupportedException; + } diff --git a/src/main/java/meerkat/crypto/concrete/SHA256Digest.java b/src/main/java/meerkat/crypto/concrete/SHA256Digest.java index eb869c6..092aab4 100644 --- a/src/main/java/meerkat/crypto/concrete/SHA256Digest.java +++ b/src/main/java/meerkat/crypto/concrete/SHA256Digest.java @@ -1,7 +1,72 @@ package meerkat.crypto.concrete; +import com.google.protobuf.Message; +import meerkat.crypto.Digest; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; + /** * Created by talm on 11/9/15. */ -public class SHA256Digest { +public class SHA256Digest implements Digest { + final Logger logger = LoggerFactory.getLogger(getClass()); + public static final String SHA256 = "SHA-256"; + + MessageDigest hash; + + /** + * Instantiate with a specified algorithm. + * @param algorithm + * @throws NoSuchAlgorithmException + */ + public SHA256Digest(String algorithm) throws NoSuchAlgorithmException { + hash = MessageDigest.getInstance(algorithm); + } + + /** + * Instantiate with the default (SHA-256) algorithm + */ + public SHA256Digest() { this(true); } + + + /** + * Instantiate with the default (SHA-256) algorithm, + * or create an empty class (for cloning) + */ + private SHA256Digest(boolean initHash) { + if (initHash) { + try { + hash = MessageDigest.getInstance(SHA256); + } catch (NoSuchAlgorithmException e) { + // Should never happen! + logger.error("Couldn't find default {} algorhtm: {}", SHA256, e); + assert false; + } + } + } + + @Override + public byte[] digest() { + return hash.digest(); + } + + @Override + public void update(Message msg) { + hash.update(msg.toByteString().asReadOnlyByteBuffer()); + } + + @Override + public void reset() { + hash.reset(); + } + + @Override + public SHA256Digest clone() throws CloneNotSupportedException { + SHA256Digest copy = new SHA256Digest(false); + copy.hash = (MessageDigest) hash.clone(); + return copy; + } }