From bce4475aaf58fe533f338ef119d6255f815e3155 Mon Sep 17 00:00:00 2001 From: Sean Gilligan Date: Fri, 15 Sep 2023 17:53:05 -0700 Subject: [PATCH] replace Guava `Bytes.concat()` with own `ByteUtils.concat()` --- .../java/org/bitcoinj/base/internal/ByteUtils.java | 13 +++++++++++++ .../java/org/bitcoinj/crypto/BIP38PrivateKey.java | 9 ++++----- .../bitcoinj/crypto/utils/MessageVerifyUtils.java | 4 ++-- .../test/java/org/bitcoinj/crypto/ECKeyTest.java | 3 +-- .../java/org/bitcoinj/script/ScriptChunkTest.java | 10 +++++----- 5 files changed, 25 insertions(+), 14 deletions(-) diff --git a/core/src/main/java/org/bitcoinj/base/internal/ByteUtils.java b/core/src/main/java/org/bitcoinj/base/internal/ByteUtils.java index cae8a3209..f34afb9a1 100644 --- a/core/src/main/java/org/bitcoinj/base/internal/ByteUtils.java +++ b/core/src/main/java/org/bitcoinj/base/internal/ByteUtils.java @@ -742,4 +742,17 @@ public class ByteUtils { private static int compareUnsigned(byte a, byte b) { return Byte.toUnsignedInt(a) - Byte.toUnsignedInt(b); } + + /** + * Concatentate two byte arrays + * @param b1 first byte array + * @param b2 second byte array + * @return new concatenated byte array + */ + public static byte[] concat(byte[] b1, byte[] b2) { + byte[] result = new byte[b1.length + b2.length]; + System.arraycopy(b1, 0, result, 0, b1.length); + System.arraycopy(b2, 0, result, b1.length, b2.length); + return result; + } } diff --git a/core/src/main/java/org/bitcoinj/crypto/BIP38PrivateKey.java b/core/src/main/java/org/bitcoinj/crypto/BIP38PrivateKey.java index 2003d9d30..1c9c1f5b7 100644 --- a/core/src/main/java/org/bitcoinj/crypto/BIP38PrivateKey.java +++ b/core/src/main/java/org/bitcoinj/crypto/BIP38PrivateKey.java @@ -16,7 +16,6 @@ package org.bitcoinj.crypto; -import com.google.common.primitives.Bytes; import org.bitcoinj.base.Network; import org.bitcoinj.base.ScriptType; import org.bitcoinj.base.internal.ByteUtils; @@ -169,14 +168,14 @@ public class BIP38PrivateKey extends EncodedPrivateKey { byte[] passFactorBytes = SCrypt.generate(normalizedPassphrase.getBytes(StandardCharsets.UTF_8), ownerSalt, 16384, 8, 8, 32); if (hasLotAndSequence) { - byte[] hashBytes = Bytes.concat(passFactorBytes, ownerEntropy); + byte[] hashBytes = ByteUtils.concat(passFactorBytes, ownerEntropy); checkState(hashBytes.length == 40); passFactorBytes = Sha256Hash.hashTwice(hashBytes); } BigInteger passFactor = ByteUtils.bytesToBigInteger(passFactorBytes); ECKey k = ECKey.fromPrivate(passFactor, true); - byte[] salt = Bytes.concat(addressHash, ownerEntropy); + byte[] salt = ByteUtils.concat(addressHash, ownerEntropy); checkState(salt.length == 12); byte[] derived = SCrypt.generate(k.getPubKey(), salt, 1024, 1, 1, 64); byte[] aeskey = Arrays.copyOfRange(derived, 32, 64); @@ -191,13 +190,13 @@ public class BIP38PrivateKey extends EncodedPrivateKey { for (int i = 0; i < 16; i++) decrypted2[i] ^= derived[i + 16]; - byte[] encrypted1 = Bytes.concat(Arrays.copyOfRange(content, 8, 16), Arrays.copyOfRange(decrypted2, 0, 8)); + byte[] encrypted1 = ByteUtils.concat(Arrays.copyOfRange(content, 8, 16), Arrays.copyOfRange(decrypted2, 0, 8)); byte[] decrypted1 = cipher.doFinal(encrypted1); checkState(decrypted1.length == 16); for (int i = 0; i < 16; i++) decrypted1[i] ^= derived[i]; - byte[] seed = Bytes.concat(decrypted1, Arrays.copyOfRange(decrypted2, 8, 16)); + byte[] seed = ByteUtils.concat(decrypted1, Arrays.copyOfRange(decrypted2, 8, 16)); checkState(seed.length == 24); BigInteger seedFactor = ByteUtils.bytesToBigInteger(Sha256Hash.hashTwice(seed)); checkState(passFactor.signum() >= 0); diff --git a/core/src/main/java/org/bitcoinj/crypto/utils/MessageVerifyUtils.java b/core/src/main/java/org/bitcoinj/crypto/utils/MessageVerifyUtils.java index 66ece3601..b1ad52edb 100644 --- a/core/src/main/java/org/bitcoinj/crypto/utils/MessageVerifyUtils.java +++ b/core/src/main/java/org/bitcoinj/crypto/utils/MessageVerifyUtils.java @@ -1,9 +1,9 @@ package org.bitcoinj.crypto.utils; -import com.google.common.primitives.Bytes; import org.bitcoinj.base.LegacyAddress; import org.bitcoinj.base.ScriptType; import org.bitcoinj.base.Address; +import org.bitcoinj.base.internal.ByteUtils; import org.bitcoinj.crypto.ECKey; import org.bitcoinj.base.SegwitAddress; import org.bitcoinj.crypto.internal.CryptoUtils; @@ -128,6 +128,6 @@ public class MessageVerifyUtils { // 0x14 is OP_PUSH_20, pushes the next 20 bytes (=length of the pubkeyHash) on the stack // (it's safe to hardcode version 0 here, as P2SH-wrapping is only defined for segwit version 0) final byte[] scriptPubKeyPrefix = {0x00, 0x14}; - return Bytes.concat(scriptPubKeyPrefix, pubKeyHash); + return ByteUtils.concat(scriptPubKeyPrefix, pubKeyHash); } } diff --git a/core/src/test/java/org/bitcoinj/crypto/ECKeyTest.java b/core/src/test/java/org/bitcoinj/crypto/ECKeyTest.java index e6474897a..c7a8efe86 100644 --- a/core/src/test/java/org/bitcoinj/crypto/ECKeyTest.java +++ b/core/src/test/java/org/bitcoinj/crypto/ECKeyTest.java @@ -18,7 +18,6 @@ package org.bitcoinj.crypto; import com.google.common.collect.Lists; -import com.google.common.primitives.Bytes; import org.bitcoinj.base.Address; import org.bitcoinj.base.LegacyAddress; import org.bitcoinj.base.ScriptType; @@ -310,7 +309,7 @@ public class ECKeyTest { Address expectedAddress = LegacyAddress.fromBase58("3HnHC8dJCqixUBFNYXdz2LFXQwvAkkTR3m", MAINNET); ECKey key = ECKey.signedMessageToKey(message, sigBase64); final byte[] segwitV0_OpPush20 = {0x00, 0x14}; - byte[] segwitV0ScriptPubKey = Bytes.concat(segwitV0_OpPush20, key.getPubKeyHash()); // as defined in BIP 141 + byte[] segwitV0ScriptPubKey = ByteUtils.concat(segwitV0_OpPush20, key.getPubKeyHash()); // as defined in BIP 141 byte[] scriptHashOfSegwitScript = CryptoUtils.sha256hash160(segwitV0ScriptPubKey); Address gotAddress = LegacyAddress.fromScriptHash(MAINNET, scriptHashOfSegwitScript); assertEquals(expectedAddress, gotAddress); diff --git a/core/src/test/java/org/bitcoinj/script/ScriptChunkTest.java b/core/src/test/java/org/bitcoinj/script/ScriptChunkTest.java index fcfbd79c3..8e82654fb 100644 --- a/core/src/test/java/org/bitcoinj/script/ScriptChunkTest.java +++ b/core/src/test/java/org/bitcoinj/script/ScriptChunkTest.java @@ -16,8 +16,8 @@ package org.bitcoinj.script; -import com.google.common.primitives.Bytes; import nl.jqno.equalsverifier.EqualsVerifier; +import org.bitcoinj.base.internal.ByteUtils; import org.junit.Test; import java.util.Random; @@ -96,7 +96,7 @@ public class ScriptChunkTest { for (byte len = 1; len < OP_PUSHDATA1; len++) { byte[] bytes = new byte[len]; RANDOM.nextBytes(bytes); - byte[] expected = Bytes.concat(new byte[] { len }, bytes); + byte[] expected = ByteUtils.concat(new byte[] { len }, bytes); byte[] actual = new ScriptChunk(len, bytes).toByteArray(); assertArrayEquals(expected, actual); } @@ -107,7 +107,7 @@ public class ScriptChunkTest { // OP_PUSHDATA1 byte[] bytes = new byte[0xFF]; RANDOM.nextBytes(bytes); - byte[] expected = Bytes.concat(new byte[] { OP_PUSHDATA1, (byte) 0xFF }, bytes); + byte[] expected = ByteUtils.concat(new byte[] { OP_PUSHDATA1, (byte) 0xFF }, bytes); byte[] actual = new ScriptChunk(OP_PUSHDATA1, bytes).toByteArray(); assertArrayEquals(expected, actual); } @@ -117,7 +117,7 @@ public class ScriptChunkTest { // OP_PUSHDATA2 byte[] bytes = new byte[0x0102]; RANDOM.nextBytes(bytes); - byte[] expected = Bytes.concat(new byte[] { OP_PUSHDATA2, 0x02, 0x01 }, bytes); + byte[] expected = ByteUtils.concat(new byte[] { OP_PUSHDATA2, 0x02, 0x01 }, bytes); byte[] actual = new ScriptChunk(OP_PUSHDATA2, bytes).toByteArray(); assertArrayEquals(expected, actual); } @@ -127,7 +127,7 @@ public class ScriptChunkTest { // OP_PUSHDATA4 byte[] bytes = new byte[0x0102]; RANDOM.nextBytes(bytes); - byte[] expected = Bytes.concat(new byte[] { OP_PUSHDATA4, 0x02, 0x01, 0x00, 0x00 }, bytes); + byte[] expected = ByteUtils.concat(new byte[] { OP_PUSHDATA4, 0x02, 0x01, 0x00, 0x00 }, bytes); byte[] actual = new ScriptChunk(OP_PUSHDATA4, bytes).toByteArray(); assertArrayEquals(expected, actual); }