From 2fd96c777164dd812e8b5a4294b162889601df1d Mon Sep 17 00:00:00 2001 From: Amichai Rothman Date: Mon, 22 Jun 2015 18:37:14 +0300 Subject: [PATCH] extracted common Utils.newSha256Digest() method to reduce boilerplate code --- .../org/bitcoinj/core/CheckpointManager.java | 5 +-- .../java/org/bitcoinj/core/Sha256Hash.java | 7 +--- .../main/java/org/bitcoinj/core/Utils.java | 41 +++++++++++-------- .../org/bitcoinj/crypto/MnemonicCode.java | 8 +--- .../main/java/org/bitcoinj/script/Script.java | 6 +-- .../org/bitcoinj/tools/BuildCheckpoints.java | 2 +- 6 files changed, 28 insertions(+), 41 deletions(-) diff --git a/core/src/main/java/org/bitcoinj/core/CheckpointManager.java b/core/src/main/java/org/bitcoinj/core/CheckpointManager.java index 55652ac5a..2f63b6c61 100644 --- a/core/src/main/java/org/bitcoinj/core/CheckpointManager.java +++ b/core/src/main/java/org/bitcoinj/core/CheckpointManager.java @@ -38,7 +38,6 @@ import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.security.DigestInputStream; import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; import java.util.Arrays; import java.util.Map; import java.util.TreeMap; @@ -101,7 +100,7 @@ public class CheckpointManager { private Sha256Hash readBinary(InputStream inputStream) throws IOException { DataInputStream dis = null; try { - MessageDigest digest = MessageDigest.getInstance("SHA-256"); + MessageDigest digest = Utils.newSha256Digest(); DigestInputStream digestInputStream = new DigestInputStream(inputStream, digest); dis = new DataInputStream(digestInputStream); digestInputStream.on(false); @@ -130,8 +129,6 @@ public class CheckpointManager { Sha256Hash dataHash = new Sha256Hash(digest.digest()); log.info("Read {} checkpoints, hash is {}", checkpoints.size(), dataHash); return dataHash; - } catch (NoSuchAlgorithmException e) { - throw new RuntimeException(e); // Cannot happen. } catch (ProtocolException e) { throw new IOException(e); } finally { diff --git a/core/src/main/java/org/bitcoinj/core/Sha256Hash.java b/core/src/main/java/org/bitcoinj/core/Sha256Hash.java index 593e98ab5..11a2f53c9 100644 --- a/core/src/main/java/org/bitcoinj/core/Sha256Hash.java +++ b/core/src/main/java/org/bitcoinj/core/Sha256Hash.java @@ -65,12 +65,7 @@ public class Sha256Hash implements Serializable, Comparable { * Calculates the (one-time) hash of contents and returns it. */ public static Sha256Hash hash(byte[] contents) { - try { - MessageDigest digest = MessageDigest.getInstance("SHA-256"); - return new Sha256Hash(digest.digest(contents)); - } catch (NoSuchAlgorithmException e) { - throw new RuntimeException(e); // Cannot happen. - } + return new Sha256Hash(Utils.newSha256Digest().digest(contents)); } /** Use hashTwice(byte[]) instead: this old name is ambiguous. */ diff --git a/core/src/main/java/org/bitcoinj/core/Utils.java b/core/src/main/java/org/bitcoinj/core/Utils.java index 22685102e..05aa82d5f 100644 --- a/core/src/main/java/org/bitcoinj/core/Utils.java +++ b/core/src/main/java/org/bitcoinj/core/Utils.java @@ -50,14 +50,7 @@ import static com.google.common.util.concurrent.Uninterruptibles.sleepUninterrup * To enable debug logging from the library, run with -Dbitcoinj.logging=true on your command line. */ public class Utils { - private static final MessageDigest digest; - static { - try { - digest = MessageDigest.getInstance("SHA-256"); - } catch (NoSuchAlgorithmException e) { - throw new RuntimeException(e); // Can't happen. - } - } + private static final MessageDigest digest = newSha256Digest(); /** The string that prefixes all text messages signed using Bitcoin keys. */ public static final String BITCOIN_SIGNED_MESSAGE_HEADER = "Bitcoin Signed Message:\n"; @@ -65,6 +58,22 @@ public class Utils { private static BlockingQueue mockSleepQueue; + /** + * Returns a new SHA-256 MessageDigest instance. + * + * This is a convenience method which wraps the checked + * exception that can never occur with a RuntimeException. + * + * @return a new SHA-256 MessageDigest instance + */ + public static MessageDigest newSha256Digest() { + try { + return MessageDigest.getInstance("SHA-256"); + } catch (NoSuchAlgorithmException e) { + throw new RuntimeException(e); // Can't happen. + } + } + /** * The regular {@link java.math.BigInteger#toByteArray()} method isn't quite what we often need: it appends a * leading zero to indicate that the number is positive and may need padding. @@ -268,16 +277,12 @@ public class Utils { * Calculates RIPEMD160(SHA256(input)). This is used in Address calculations. */ public static byte[] sha256hash160(byte[] input) { - try { - byte[] sha256 = MessageDigest.getInstance("SHA-256").digest(input); - RIPEMD160Digest digest = new RIPEMD160Digest(); - digest.update(sha256, 0, sha256.length); - byte[] out = new byte[20]; - digest.doFinal(out, 0); - return out; - } catch (NoSuchAlgorithmException e) { - throw new RuntimeException(e); // Cannot happen. - } + byte[] sha256 = newSha256Digest().digest(input); + RIPEMD160Digest digest = new RIPEMD160Digest(); + digest.update(sha256, 0, sha256.length); + byte[] out = new byte[20]; + digest.doFinal(out, 0); + return out; } /** diff --git a/core/src/main/java/org/bitcoinj/crypto/MnemonicCode.java b/core/src/main/java/org/bitcoinj/crypto/MnemonicCode.java index 9e9cd8290..241fcc085 100644 --- a/core/src/main/java/org/bitcoinj/crypto/MnemonicCode.java +++ b/core/src/main/java/org/bitcoinj/crypto/MnemonicCode.java @@ -29,7 +29,6 @@ import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -88,12 +87,7 @@ public class MnemonicCode { public MnemonicCode(InputStream wordstream, String wordListDigest) throws IOException, IllegalArgumentException { BufferedReader br = new BufferedReader(new InputStreamReader(wordstream, "UTF-8")); this.wordList = new ArrayList(2048); - MessageDigest md; - try { - md = MessageDigest.getInstance("SHA-256"); - } catch (NoSuchAlgorithmException ex) { - throw new RuntimeException(ex); // Can't happen. - } + MessageDigest md = Utils.newSha256Digest(); String word; while ((word = br.readLine()) != null) { md.update(word.getBytes()); diff --git a/core/src/main/java/org/bitcoinj/script/Script.java b/core/src/main/java/org/bitcoinj/script/Script.java index c30c574fa..e14e7af86 100644 --- a/core/src/main/java/org/bitcoinj/script/Script.java +++ b/core/src/main/java/org/bitcoinj/script/Script.java @@ -1223,11 +1223,7 @@ public class Script { case OP_SHA256: if (stack.size() < 1) throw new ScriptException("Attempted OP_SHA256 on an empty stack"); - try { - stack.add(MessageDigest.getInstance("SHA-256").digest(stack.pollLast())); - } catch (NoSuchAlgorithmException e) { - throw new RuntimeException(e); // Cannot happen. - } + stack.add(Utils.newSha256Digest().digest(stack.pollLast())); break; case OP_HASH160: if (stack.size() < 1) diff --git a/tools/src/main/java/org/bitcoinj/tools/BuildCheckpoints.java b/tools/src/main/java/org/bitcoinj/tools/BuildCheckpoints.java index 663839643..064bbf9a6 100644 --- a/tools/src/main/java/org/bitcoinj/tools/BuildCheckpoints.java +++ b/tools/src/main/java/org/bitcoinj/tools/BuildCheckpoints.java @@ -101,7 +101,7 @@ public class BuildCheckpoints { private static void writeBinaryCheckpoints(TreeMap checkpoints, File file) throws Exception { final FileOutputStream fileOutputStream = new FileOutputStream(file, false); - MessageDigest digest = MessageDigest.getInstance("SHA-256"); + MessageDigest digest = Utils.newSha256Digest(); final DigestOutputStream digestOutputStream = new DigestOutputStream(fileOutputStream, digest); digestOutputStream.on(false); final DataOutputStream dataOutputStream = new DataOutputStream(digestOutputStream);