3
0
mirror of https://github.com/Qortal/altcoinj.git synced 2025-02-14 19:25:51 +00:00

- changed unused Utils.singleDigest method to use new MessageDigest instances rather than a synchronized singleton

- replaced verbose hash computations with calls to Utils.singleDigest/doubleDigest
- added javadocs to Utils.singleDigest/doubleDigest
This commit is contained in:
Amichai Rothman 2015-06-22 21:04:04 +03:00 committed by Mike Hearn
parent 772aa300df
commit a449e3b026
9 changed files with 45 additions and 21 deletions

View File

@ -65,7 +65,7 @@ public class Sha256Hash implements Serializable, Comparable<Sha256Hash> {
* Calculates the (one-time) hash of contents and returns it.
*/
public static Sha256Hash hash(byte[] contents) {
return new Sha256Hash(Utils.newSha256Digest().digest(contents));
return new Sha256Hash(Utils.singleDigest(contents));
}
/** Use hashTwice(byte[]) instead: this old name is ambiguous. */

View File

@ -151,15 +151,24 @@ public class Utils {
}
/**
* See {@link Utils#doubleDigest(byte[], int, int)}.
* Calculates the SHA-256 hash of the given bytes,
* and then hashes the resulting hash again.
*
* @param input the bytes to hash
* @return the double-hash (in big-endian order)
*/
public static byte[] doubleDigest(byte[] input) {
return doubleDigest(input, 0, input.length);
}
/**
* Calculates the SHA-256 hash of the given byte range, and then hashes the resulting hash again. This is
* standard procedure in Bitcoin. The resulting hash is in big endian form.
* Calculates the SHA-256 hash of the given byte range,
* and then hashes the resulting hash again.
*
* @param input the array containing the bytes to hash
* @param offset the offset within the array of the bytes to hash
* @param length the number of bytes to hash
* @return the double-hash (in big-endian order)
*/
public static byte[] doubleDigest(byte[] input, int offset, int length) {
synchronized (digest) {
@ -170,12 +179,28 @@ public class Utils {
}
}
/**
* Calculates the SHA-256 hash of the given bytes.
*
* @param input the bytes to hash
* @return the hash (in big-endian order)
*/
public static byte[] singleDigest(byte[] input) {
return singleDigest(input, 0, input.length);
}
/**
* Calculates the SHA-256 hash of the given byte range.
*
* @param input the array containing the bytes to hash
* @param offset the offset within the array of the bytes to hash
* @param length the number of bytes to hash
* @return the hash (in big-endian order)
*/
public static byte[] singleDigest(byte[] input, int offset, int length) {
synchronized (digest) {
digest.reset();
digest.update(input, offset, length);
return digest.digest();
}
MessageDigest digest = newSha256Digest();
digest.update(input, offset, length);
return digest.digest();
}
/**
@ -277,7 +302,7 @@ public class Utils {
* Calculates RIPEMD160(SHA256(input)). This is used in Address calculations.
*/
public static byte[] sha256hash160(byte[] input) {
byte[] sha256 = newSha256Digest().digest(input);
byte[] sha256 = singleDigest(input);
RIPEMD160Digest digest = new RIPEMD160Digest();
digest.update(sha256, 0, sha256.length);
byte[] out = new byte[20];

View File

@ -122,7 +122,7 @@ public class BIP38PrivateKey extends VersionedChecksummedBytes {
if (hasLotAndSequence) {
byte[] hashBytes = Bytes.concat(passFactorBytes, ownerEntropy);
checkState(hashBytes.length == 40);
passFactorBytes = Sha256Hash.hashTwice(hashBytes).getBytes();
passFactorBytes = Utils.doubleDigest(hashBytes);
}
BigInteger passFactor = new BigInteger(1, passFactorBytes);
ECKey k = ECKey.fromPrivate(passFactor, true);
@ -150,7 +150,7 @@ public class BIP38PrivateKey extends VersionedChecksummedBytes {
byte[] seed = Bytes.concat(decrypted1, Arrays.copyOfRange(decrypted2, 8, 16));
checkState(seed.length == 24);
BigInteger seedFactor = new BigInteger(1, Sha256Hash.hashTwice(seed).getBytes());
BigInteger seedFactor = new BigInteger(1, Utils.doubleDigest(seed));
checkState(passFactor.signum() >= 0);
checkState(seedFactor.signum() >= 0);
BigInteger priv = passFactor.multiply(seedFactor).mod(ECKey.CURVE.getN());

View File

@ -17,7 +17,6 @@
package org.bitcoinj.crypto;
import org.bitcoinj.core.Sha256Hash;
import org.bitcoinj.core.Utils;
import com.google.common.base.Joiner;
import org.slf4j.Logger;
@ -174,7 +173,7 @@ public class MnemonicCode {
entropy[ii] |= 1 << (7 - jj);
// Take the digest of the entropy.
byte[] hash = Sha256Hash.hash(entropy).getBytes();
byte[] hash = Utils.singleDigest(entropy);
boolean[] hashBits = bytesToBits(hash);
// Check all the checksum bits.
@ -198,7 +197,7 @@ public class MnemonicCode {
// We take initial entropy of ENT bits and compute its
// checksum by taking first ENT / 32 bits of its SHA256 hash.
byte[] hash = Sha256Hash.hash(entropy).getBytes();
byte[] hash = Utils.singleDigest(entropy);
boolean[] hashBits = bytesToBits(hash);
boolean[] entropyBits = bytesToBits(entropy);

View File

@ -101,8 +101,8 @@ public class HttpDiscovery implements PeerDiscovery {
if (details.pubkey != null) {
if (!Arrays.equals(proto.getPubkey().toByteArray(), details.pubkey.getPubKey()))
throw new PeerDiscoveryException("Public key mismatch");
Sha256Hash hash = Sha256Hash.hash(proto.getPeerSeeds().toByteArray());
details.pubkey.verifyOrThrow(hash.getBytes(), proto.getSignature().toByteArray());
byte[] hash = Utils.singleDigest(proto.getPeerSeeds().toByteArray());
details.pubkey.verifyOrThrow(hash, proto.getSignature().toByteArray());
}
PeerSeedProtos.PeerSeeds seeds = PeerSeedProtos.PeerSeeds.parseFrom(proto.getPeerSeeds());
if (seeds.getTimestamp() < Utils.currentTimeSeconds() - (60 * 60 * 24))

View File

@ -1223,7 +1223,7 @@ public class Script {
case OP_SHA256:
if (stack.size() < 1)
throw new ScriptException("Attempted OP_SHA256 on an empty stack");
stack.add(Utils.newSha256Digest().digest(stack.pollLast()));
stack.add(Utils.singleDigest(stack.pollLast()));
break;
case OP_HASH160:
if (stack.size() < 1)

View File

@ -341,7 +341,7 @@ public class ChannelConnectionTest extends TestWithWallet {
pair.server.receiveMessage(Protos.TwoWayChannelMessage.newBuilder()
.setType(MessageType.CLIENT_VERSION)
.setClientVersion(Protos.ClientVersion.newBuilder()
.setPreviousChannelContractHash(ByteString.copyFrom(Sha256Hash.hash(new byte[]{0x03}).getBytes()))
.setPreviousChannelContractHash(ByteString.copyFrom(Utils.singleDigest(new byte[]{0x03})))
.setMajor(CLIENT_MAJOR_VERSION).setMinor(42))
.build());
pair.serverRecorder.checkNextMsg(MessageType.SERVER_VERSION);

View File

@ -39,7 +39,7 @@ import static org.junit.Assert.*;
public class DeterministicKeyChainTest {
private DeterministicKeyChain chain;
private final byte[] ENTROPY = Sha256Hash.hash("don't use a string seed like this in real life".getBytes()).getBytes();
private final byte[] ENTROPY = Utils.singleDigest("don't use a string seed like this in real life".getBytes());
@Before
public void setup() {

View File

@ -64,7 +64,7 @@ public class KeyChainGroupTest {
}
private MarriedKeyChain createMarriedKeyChain() {
byte[] entropy = Sha256Hash.hash("don't use a seed like this in real life".getBytes()).getBytes();
byte[] entropy = Utils.singleDigest("don't use a seed like this in real life".getBytes());
DeterministicSeed seed = new DeterministicSeed(entropy, "", MnemonicCode.BIP39_STANDARDISATION_TIME_SECS);
MarriedKeyChain chain = MarriedKeyChain.builder()
.seed(seed)