From 5201c7687704fda276fb603774036db7ec84469b Mon Sep 17 00:00:00 2001 From: Sean Gilligan Date: Sat, 17 Jan 2026 13:22:26 -0800 Subject: [PATCH 1/4] ECKey: replace Bouncy Castle `Base64` with JDK `Base64` --- core/src/main/java/org/bitcoinj/crypto/ECKey.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core/src/main/java/org/bitcoinj/crypto/ECKey.java b/core/src/main/java/org/bitcoinj/crypto/ECKey.java index b35fa65cca8..84f3e8f755d 100644 --- a/core/src/main/java/org/bitcoinj/crypto/ECKey.java +++ b/core/src/main/java/org/bitcoinj/crypto/ECKey.java @@ -62,7 +62,6 @@ import org.bouncycastle.math.ec.FixedPointUtil; import org.bouncycastle.math.ec.custom.sec.SecP256K1Curve; import org.bouncycastle.util.Properties; -import org.bouncycastle.util.encoders.Base64; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -77,6 +76,7 @@ import java.time.Instant; import java.time.temporal.ChronoUnit; import java.util.Arrays; +import java.util.Base64; import java.util.Comparator; import java.util.Objects; import java.util.Optional; @@ -869,7 +869,7 @@ public String signMessage(String message, @Nullable AesKey aesKey, ScriptType sc sigData[0] = (byte)headerByte; System.arraycopy(ByteUtils.bigIntegerToBytes(sig.r, 32), 0, sigData, 1, 32); System.arraycopy(ByteUtils.bigIntegerToBytes(sig.s, 32), 0, sigData, 33, 32); - return new String(Base64.encode(sigData), StandardCharsets.UTF_8); + return new String(Base64.getEncoder().encode(sigData), StandardCharsets.UTF_8); } /** @@ -886,7 +886,7 @@ public String signMessage(String message, @Nullable AesKey aesKey, ScriptType sc public static ECKey signedMessageToKey(String message, String signatureBase64) throws SignatureException { byte[] signatureEncoded; try { - signatureEncoded = Base64.decode(signatureBase64); + signatureEncoded = Base64.getDecoder().decode(signatureBase64); } catch (RuntimeException e) { // This is what you get back from Bouncy Castle if base64 doesn't decode :( throw new SignatureException("Could not decode base64", e); From df466d199de95a7e144439c1c478b5bced26f35a Mon Sep 17 00:00:00 2001 From: Sean Gilligan Date: Sat, 17 Jan 2026 13:25:06 -0800 Subject: [PATCH 2/4] CheckpointManager, BuildCheckpoints: replace Guava `BaseEncoding.base64()` with JDK `Base64` Deprecate the `BASE64` constant but keep it around for now. We may decide to remove it in the 0.18 cycle when we get rid of the Guava dependency. --- .../src/main/java/org/bitcoinj/core/CheckpointManager.java | 7 ++++++- .../src/main/java/org/bitcoinj/tools/BuildCheckpoints.java | 5 +++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/core/src/main/java/org/bitcoinj/core/CheckpointManager.java b/core/src/main/java/org/bitcoinj/core/CheckpointManager.java index 5549a0dddf9..1961c4e8b23 100644 --- a/core/src/main/java/org/bitcoinj/core/CheckpointManager.java +++ b/core/src/main/java/org/bitcoinj/core/CheckpointManager.java @@ -42,6 +42,7 @@ import java.time.Instant; import java.time.temporal.ChronoUnit; import java.util.Arrays; +import java.util.Base64; import java.util.Map; import java.util.Objects; import java.util.TreeMap; @@ -84,6 +85,10 @@ public class CheckpointManager { protected final NetworkParameters params; protected final Sha256Hash dataHash; + /** + * @deprecated Use {@link java.util.Base64} or a 3rd-party Base64 implementation. + */ + @Deprecated public static final BaseEncoding BASE64 = BaseEncoding.base64().omitPadding(); /** Loads the default checkpoints bundled with bitcoinj */ @@ -128,7 +133,7 @@ private Sha256Hash readTextual(InputStream inputStream) throws IOException { // Hash numCheckpoints in a way compatible to the binary format. digest.update(ByteBuffer.allocate(4).order(ByteOrder.BIG_ENDIAN).putInt(numCheckpoints).array()); for (int i = 0; i < numCheckpoints; i++) { - byte[] bytes = BASE64.decode(reader.readLine()); + byte[] bytes = Base64.getDecoder().decode(reader.readLine()); digest.update(bytes); ByteBuffer buffer = ByteBuffer.wrap(bytes); StoredBlock block; diff --git a/tools/src/main/java/org/bitcoinj/tools/BuildCheckpoints.java b/tools/src/main/java/org/bitcoinj/tools/BuildCheckpoints.java index d3996d6cc02..df3d9e6b7d4 100644 --- a/tools/src/main/java/org/bitcoinj/tools/BuildCheckpoints.java +++ b/tools/src/main/java/org/bitcoinj/tools/BuildCheckpoints.java @@ -48,6 +48,7 @@ import java.nio.charset.StandardCharsets; import java.time.Instant; import java.time.temporal.ChronoUnit; +import java.util.Base64; import java.util.List; import java.util.TreeMap; import java.util.concurrent.Callable; @@ -197,11 +198,11 @@ private static void writeTextualCheckpoints(TreeMap checkp if (block.getChainWork().compareTo(MAX_WORK_V1) <= 0) { ((Buffer) bufferV1).rewind(); block.serializeCompact(bufferV1); - writer.println(CheckpointManager.BASE64.encode(bufferV1.array())); + writer.println(Base64.getEncoder().encodeToString(bufferV1.array())); } else { ((Buffer) bufferV2).rewind(); block.serializeCompactV2(bufferV2); - writer.println(CheckpointManager.BASE64.encode(bufferV2.array())); + writer.println(Base64.getEncoder().encodeToString(bufferV2.array())); } } System.out.println("Checkpoints written to '" + file.getCanonicalPath() + "'."); From 3ecd66ad87c3103cf6a5ecee05ce074b0a4c8790 Mon Sep 17 00:00:00 2001 From: Sean Gilligan Date: Wed, 7 Jan 2026 13:34:58 -0800 Subject: [PATCH 3/4] README.adoc: require Gradle 9.1+ for building whole project Gradle 9.1+ is already required for building `wallettemplate`. --- README.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.adoc b/README.adoc index 149c00810b4..9c7c60557a9 100644 --- a/README.adoc +++ b/README.adoc @@ -14,7 +14,7 @@ The bitcoinj library is a Java implementation of the Bitcoin protocol, which all * Java 17+ for `tools`, `wallettool`, `examples` * Java 25+ for the JavaFX-based `wallettemplate` * https://gradle.org/[Gradle] -** Gradle 8.5+ for building the whole project or +** Gradle 9.1+ for building the whole project or ** Debian Gradle 4.4 for just the `base`, `core`, `tools`, `wallettool` and `examples` modules (see "reference build" below) * https://github.com/google/protobuf[Google Protocol Buffers] - for use with serialization and hardware communications From 6c7ed0d4c74a04abfde437c9e09116c1134c0748 Mon Sep 17 00:00:00 2001 From: Sean Gilligan Date: Wed, 7 Jan 2026 13:37:10 -0800 Subject: [PATCH 4/4] build-gradle.yml: remove Gradle 8.5 from the build matrix This reflects the README change in a previous commit, simplifies the build and reduces resource usage. We leave 8.14.3 in the matrix as the oldest version of Gradle we can test on GitHub Actions and as a proxy for Debian Gradle 4.4. --- .github/workflows/build-gradle.yml | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/.github/workflows/build-gradle.yml b/.github/workflows/build-gradle.yml index 1546de24a4b..54cbb122b0f 100644 --- a/.github/workflows/build-gradle.yml +++ b/.github/workflows/build-gradle.yml @@ -11,24 +11,16 @@ jobs: os: [ubuntu-24.04, macOS-15, macOS-15-intel, windows-2022] java: ['17', '21', '25'] distribution: ['temurin'] - gradle: ['8.5', '8.14.3', '9.2.1'] + gradle: ['8.14.3', '9.2.1'] exclude: # Java 25+ requires Gradle 9.1+ - - java: '25' - gradle: '8.5' - java: '25' gradle: '8.14.3' # Exclude older versions of Gradle on macOS and Windows - - os: macOS-15 - gradle: '8.5' - os: macOS-15 gradle: '8.14.3' - - os: macOS-15-intel - gradle: '8.5' - os: macOS-15-intel gradle: '8.14.3' - - os: windows-2022 - gradle: '8.5' - os: windows-2022 gradle: '8.14.3' fail-fast: false