diff --git a/.gitignore b/.gitignore
index 43a610fd89e..d5b206f13a0 100644
--- a/.gitignore
+++ b/.gitignore
@@ -10,3 +10,4 @@ bin/
out/
*.chain
*.spvchain
+.DS_Store
diff --git a/build.gradle b/build.gradle
index 43f0a5bd2bf..ed23f04127d 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,5 +1,9 @@
buildscript {
repositories {
+ mavenCentral()
+ maven {
+ url "https://deps.rsklabs.io"
+ }
jcenter()
}
@@ -10,6 +14,10 @@ buildscript {
allprojects {
repositories {
+ mavenCentral()
+ maven {
+ url "https://deps.rsklabs.io"
+ }
jcenter()
}
diff --git a/core/build.gradle b/core/build.gradle
index 1ebda452f67..14184874fce 100644
--- a/core/build.gradle
+++ b/core/build.gradle
@@ -2,12 +2,14 @@ apply plugin: 'java'
apply plugin: 'com.google.protobuf'
apply plugin: 'maven'
apply plugin: 'eclipse'
+apply plugin: 'maven-publish'
-version = '0.15.6-rsk-2'
+version = '0.15.6-rsk-3'
archivesBaseName = 'bitcoinj-core'
eclipse.project.name = 'bitcoinj-core'
dependencies {
+ compile 'co.rsk:native:1.2.1'
compile 'org.bouncycastle:bcprov-jdk15to18:1.63'
implementation 'com.google.guava:guava:28.1-android'
compile 'com.google.protobuf:protobuf-java:3.6.1'
@@ -79,6 +81,23 @@ task generatePom(dependsOn: jar) {
}
}
+publishing {
+ publications {
+ bitcoinj(MavenPublication) {
+ pom {
+ from components.java
+ licenses {
+ license {
+ name = 'GNU General Public License (GPL) version 3.0'
+ url = 'http://www.gnu.org/licenses/gpl-3.0.txt'
+ distribution = 'repo'
+ }
+ }
+ }
+ }
+ }
+}
+
artifacts {
archives sourcesJar
archives javadocJar
diff --git a/core/src/main/java/org/bitcoin/NativeSecp256k1.java b/core/src/main/java/org/bitcoin/NativeSecp256k1.java
deleted file mode 100644
index 2b271bd9c26..00000000000
--- a/core/src/main/java/org/bitcoin/NativeSecp256k1.java
+++ /dev/null
@@ -1,473 +0,0 @@
-/*
- * Copyright 2013 Google Inc.
- * Copyright 2014-2016 the libsecp256k1 contributors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.bitcoin;
-
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-
-import java.math.BigInteger;
-import com.google.common.base.Preconditions;
-import java.util.concurrent.locks.Lock;
-import java.util.concurrent.locks.ReentrantReadWriteLock;
-import static org.bitcoin.NativeSecp256k1Util.*;
-
-/**
- *
This class holds native methods to handle ECDSA verification.
- *
- * You can find an example library that can be used for this at https://github.com/bitcoin/secp256k1
- *
- * To build secp256k1 for use with bitcoinj, run
- * `./configure --enable-jni --enable-experimental --enable-module-schnorr --enable-module-ecdh`
- * and `make` then copy `.libs/libsecp256k1.so` to your system library path
- * or point the JVM to the folder containing it with -Djava.library.path
- *
- */
-public class NativeSecp256k1 {
-
- private static final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
- private static final Lock r = rwl.readLock();
- private static final Lock w = rwl.writeLock();
- private static ThreadLocal nativeECDSABuffer = new ThreadLocal<>();
-
- /**
- * Verifies the given secp256k1 signature in native code. Calling when enabled == false is undefined (probably
- * library not loaded)
- *
- * @param data The data which was signed, must be exactly 32 bytes
- * @param signature The signature
- * @param pub The public key which did the signing
- */
- public static boolean verify(byte[] data, byte[] signature, byte[] pub) throws AssertFailException {
- Preconditions.checkArgument(data.length == 32 && signature.length <= 520 && pub.length <= 520);
-
- ByteBuffer byteBuff = nativeECDSABuffer.get();
- if (byteBuff == null || byteBuff.capacity() < 520) {
- byteBuff = ByteBuffer.allocateDirect(520);
- byteBuff.order(ByteOrder.nativeOrder());
- nativeECDSABuffer.set(byteBuff);
- }
- byteBuff.rewind();
- byteBuff.put(data);
- byteBuff.put(signature);
- byteBuff.put(pub);
-
- r.lock();
- try {
- return secp256k1_ecdsa_verify(byteBuff, Secp256k1Context.getContext(), signature.length, pub.length) == 1;
- } finally {
- r.unlock();
- }
- }
-
- /**
- * libsecp256k1 Create an ECDSA signature.
- *
- * @param data Message hash, 32 bytes
- * @param sec Secret key, 32 bytes
- * @return sig byte array of signature
- */
- public static byte[] sign(byte[] data, byte[] sec) throws AssertFailException {
- Preconditions.checkArgument(data.length == 32 && sec.length <= 32);
-
- ByteBuffer byteBuff = nativeECDSABuffer.get();
- if (byteBuff == null || byteBuff.capacity() < 32 + 32) {
- byteBuff = ByteBuffer.allocateDirect(32 + 32);
- byteBuff.order(ByteOrder.nativeOrder());
- nativeECDSABuffer.set(byteBuff);
- }
- byteBuff.rewind();
- byteBuff.put(data);
- byteBuff.put(sec);
-
- byte[][] retByteArray;
-
- r.lock();
- try {
- retByteArray = secp256k1_ecdsa_sign(byteBuff, Secp256k1Context.getContext());
- } finally {
- r.unlock();
- }
-
- byte[] sigArr = retByteArray[0];
- int sigLen = new BigInteger(new byte[] { retByteArray[1][0] }).intValue();
- int retVal = new BigInteger(new byte[] { retByteArray[1][1] }).intValue();
-
- assertEquals(sigArr.length, sigLen, "Got bad signature length.");
-
- return retVal == 0 ? new byte[0] : sigArr;
- }
-
- /**
- * libsecp256k1 Seckey Verify - returns 1 if valid, 0 if invalid
- *
- * @param seckey ECDSA Secret key, 32 bytes
- */
- public static boolean secKeyVerify(byte[] seckey) {
- Preconditions.checkArgument(seckey.length == 32);
-
- ByteBuffer byteBuff = nativeECDSABuffer.get();
- if (byteBuff == null || byteBuff.capacity() < seckey.length) {
- byteBuff = ByteBuffer.allocateDirect(seckey.length);
- byteBuff.order(ByteOrder.nativeOrder());
- nativeECDSABuffer.set(byteBuff);
- }
- byteBuff.rewind();
- byteBuff.put(seckey);
-
- r.lock();
- try {
- return secp256k1_ec_seckey_verify(byteBuff, Secp256k1Context.getContext()) == 1;
- } finally {
- r.unlock();
- }
- }
-
- /**
- * libsecp256k1 Compute Pubkey - computes public key from secret key
- *
- * @param seckey ECDSA Secret key, 32 bytes
- * @return pubkey ECDSA Public key, 33 or 65 bytes
- */
- // TODO add a 'compressed' arg
- public static byte[] computePubkey(byte[] seckey) throws AssertFailException {
- Preconditions.checkArgument(seckey.length == 32);
-
- ByteBuffer byteBuff = nativeECDSABuffer.get();
- if (byteBuff == null || byteBuff.capacity() < seckey.length) {
- byteBuff = ByteBuffer.allocateDirect(seckey.length);
- byteBuff.order(ByteOrder.nativeOrder());
- nativeECDSABuffer.set(byteBuff);
- }
- byteBuff.rewind();
- byteBuff.put(seckey);
-
- byte[][] retByteArray;
-
- r.lock();
- try {
- retByteArray = secp256k1_ec_pubkey_create(byteBuff, Secp256k1Context.getContext());
- } finally {
- r.unlock();
- }
-
- byte[] pubArr = retByteArray[0];
- int pubLen = new BigInteger(new byte[] { retByteArray[1][0] }).intValue();
- int retVal = new BigInteger(new byte[] { retByteArray[1][1] }).intValue();
-
- assertEquals(pubArr.length, pubLen, "Got bad pubkey length.");
-
- return retVal == 0 ? new byte[0] : pubArr;
- }
-
- /**
- * libsecp256k1 Cleanup - This destroys the secp256k1 context object This should be called at the end of the program
- * for proper cleanup of the context.
- */
- public static synchronized void cleanup() {
- w.lock();
- try {
- secp256k1_destroy_context(Secp256k1Context.getContext());
- } finally {
- w.unlock();
- }
- }
-
- public static long cloneContext() {
- r.lock();
- try {
- return secp256k1_ctx_clone(Secp256k1Context.getContext());
- } finally {
- r.unlock();
- }
- }
-
- /**
- * libsecp256k1 PrivKey Tweak-Mul - Tweak privkey by multiplying to it
- *
- * @param tweak some bytes to tweak with
- * @param privkey 32-byte seckey
- */
- public static byte[] privKeyTweakMul(byte[] privkey, byte[] tweak) throws AssertFailException {
- Preconditions.checkArgument(privkey.length == 32);
-
- ByteBuffer byteBuff = nativeECDSABuffer.get();
- if (byteBuff == null || byteBuff.capacity() < privkey.length + tweak.length) {
- byteBuff = ByteBuffer.allocateDirect(privkey.length + tweak.length);
- byteBuff.order(ByteOrder.nativeOrder());
- nativeECDSABuffer.set(byteBuff);
- }
- byteBuff.rewind();
- byteBuff.put(privkey);
- byteBuff.put(tweak);
-
- byte[][] retByteArray;
- r.lock();
- try {
- retByteArray = secp256k1_privkey_tweak_mul(byteBuff, Secp256k1Context.getContext());
- } finally {
- r.unlock();
- }
-
- byte[] privArr = retByteArray[0];
-
- int privLen = (byte) new BigInteger(new byte[] { retByteArray[1][0] }).intValue() & 0xFF;
- int retVal = new BigInteger(new byte[] { retByteArray[1][1] }).intValue();
-
- assertEquals(privArr.length, privLen, "Got bad pubkey length.");
-
- assertEquals(retVal, 1, "Failed return value check.");
-
- return privArr;
- }
-
- /**
- * libsecp256k1 PrivKey Tweak-Add - Tweak privkey by adding to it
- *
- * @param tweak some bytes to tweak with
- * @param privkey 32-byte seckey
- */
- public static byte[] privKeyTweakAdd(byte[] privkey, byte[] tweak) throws AssertFailException {
- Preconditions.checkArgument(privkey.length == 32);
-
- ByteBuffer byteBuff = nativeECDSABuffer.get();
- if (byteBuff == null || byteBuff.capacity() < privkey.length + tweak.length) {
- byteBuff = ByteBuffer.allocateDirect(privkey.length + tweak.length);
- byteBuff.order(ByteOrder.nativeOrder());
- nativeECDSABuffer.set(byteBuff);
- }
- byteBuff.rewind();
- byteBuff.put(privkey);
- byteBuff.put(tweak);
-
- byte[][] retByteArray;
- r.lock();
- try {
- retByteArray = secp256k1_privkey_tweak_add(byteBuff, Secp256k1Context.getContext());
- } finally {
- r.unlock();
- }
-
- byte[] privArr = retByteArray[0];
-
- int privLen = (byte) new BigInteger(new byte[] { retByteArray[1][0] }).intValue() & 0xFF;
- int retVal = new BigInteger(new byte[] { retByteArray[1][1] }).intValue();
-
- assertEquals(privArr.length, privLen, "Got bad pubkey length.");
-
- assertEquals(retVal, 1, "Failed return value check.");
-
- return privArr;
- }
-
- /**
- * libsecp256k1 PubKey Tweak-Add - Tweak pubkey by adding to it
- *
- * @param tweak some bytes to tweak with
- * @param pubkey 32-byte seckey
- */
- public static byte[] pubKeyTweakAdd(byte[] pubkey, byte[] tweak) throws AssertFailException {
- Preconditions.checkArgument(pubkey.length == 33 || pubkey.length == 65);
-
- ByteBuffer byteBuff = nativeECDSABuffer.get();
- if (byteBuff == null || byteBuff.capacity() < pubkey.length + tweak.length) {
- byteBuff = ByteBuffer.allocateDirect(pubkey.length + tweak.length);
- byteBuff.order(ByteOrder.nativeOrder());
- nativeECDSABuffer.set(byteBuff);
- }
- byteBuff.rewind();
- byteBuff.put(pubkey);
- byteBuff.put(tweak);
-
- byte[][] retByteArray;
- r.lock();
- try {
- retByteArray = secp256k1_pubkey_tweak_add(byteBuff, Secp256k1Context.getContext(), pubkey.length);
- } finally {
- r.unlock();
- }
-
- byte[] pubArr = retByteArray[0];
-
- int pubLen = (byte) new BigInteger(new byte[] { retByteArray[1][0] }).intValue() & 0xFF;
- int retVal = new BigInteger(new byte[] { retByteArray[1][1] }).intValue();
-
- assertEquals(pubArr.length, pubLen, "Got bad pubkey length.");
-
- assertEquals(retVal, 1, "Failed return value check.");
-
- return pubArr;
- }
-
- /**
- * libsecp256k1 PubKey Tweak-Mul - Tweak pubkey by multiplying to it
- *
- * @param tweak some bytes to tweak with
- * @param pubkey 32-byte seckey
- */
- public static byte[] pubKeyTweakMul(byte[] pubkey, byte[] tweak) throws AssertFailException {
- Preconditions.checkArgument(pubkey.length == 33 || pubkey.length == 65);
-
- ByteBuffer byteBuff = nativeECDSABuffer.get();
- if (byteBuff == null || byteBuff.capacity() < pubkey.length + tweak.length) {
- byteBuff = ByteBuffer.allocateDirect(pubkey.length + tweak.length);
- byteBuff.order(ByteOrder.nativeOrder());
- nativeECDSABuffer.set(byteBuff);
- }
- byteBuff.rewind();
- byteBuff.put(pubkey);
- byteBuff.put(tweak);
-
- byte[][] retByteArray;
- r.lock();
- try {
- retByteArray = secp256k1_pubkey_tweak_mul(byteBuff, Secp256k1Context.getContext(), pubkey.length);
- } finally {
- r.unlock();
- }
-
- byte[] pubArr = retByteArray[0];
-
- int pubLen = (byte) new BigInteger(new byte[] { retByteArray[1][0] }).intValue() & 0xFF;
- int retVal = new BigInteger(new byte[] { retByteArray[1][1] }).intValue();
-
- assertEquals(pubArr.length, pubLen, "Got bad pubkey length.");
-
- assertEquals(retVal, 1, "Failed return value check.");
-
- return pubArr;
- }
-
- /**
- * libsecp256k1 create ECDH secret - constant time ECDH calculation
- *
- * @param seckey byte array of secret key used in exponentiaion
- * @param pubkey byte array of public key used in exponentiaion
- */
- public static byte[] createECDHSecret(byte[] seckey, byte[] pubkey) throws AssertFailException {
- Preconditions.checkArgument(seckey.length <= 32 && pubkey.length <= 65);
-
- ByteBuffer byteBuff = nativeECDSABuffer.get();
- if (byteBuff == null || byteBuff.capacity() < 32 + pubkey.length) {
- byteBuff = ByteBuffer.allocateDirect(32 + pubkey.length);
- byteBuff.order(ByteOrder.nativeOrder());
- nativeECDSABuffer.set(byteBuff);
- }
- byteBuff.rewind();
- byteBuff.put(seckey);
- byteBuff.put(pubkey);
-
- byte[][] retByteArray;
- r.lock();
- try {
- retByteArray = secp256k1_ecdh(byteBuff, Secp256k1Context.getContext(), pubkey.length);
- } finally {
- r.unlock();
- }
-
- byte[] resArr = retByteArray[0];
- int retVal = new BigInteger(new byte[] { retByteArray[1][0] }).intValue();
-
- assertEquals(resArr.length, 32, "Got bad result length.");
- assertEquals(retVal, 1, "Failed return value check.");
-
- return resArr;
- }
-
- /**
- * libsecp256k1 randomize - updates the context randomization
- *
- * @param seed 32-byte random seed
- */
- public static synchronized boolean randomize(byte[] seed) throws AssertFailException {
- Preconditions.checkArgument(seed.length == 32 || seed == null);
-
- ByteBuffer byteBuff = nativeECDSABuffer.get();
- if (byteBuff == null || byteBuff.capacity() < seed.length) {
- byteBuff = ByteBuffer.allocateDirect(seed.length);
- byteBuff.order(ByteOrder.nativeOrder());
- nativeECDSABuffer.set(byteBuff);
- }
- byteBuff.rewind();
- byteBuff.put(seed);
-
- w.lock();
- try {
- return secp256k1_context_randomize(byteBuff, Secp256k1Context.getContext()) == 1;
- } finally {
- w.unlock();
- }
- }
-
- public static byte[] schnorrSign(byte[] data, byte[] sec) throws AssertFailException {
- Preconditions.checkArgument(data.length == 32 && sec.length <= 32);
-
- ByteBuffer byteBuff = nativeECDSABuffer.get();
- if (byteBuff == null) {
- byteBuff = ByteBuffer.allocateDirect(32 + 32);
- byteBuff.order(ByteOrder.nativeOrder());
- nativeECDSABuffer.set(byteBuff);
- }
- byteBuff.rewind();
- byteBuff.put(data);
- byteBuff.put(sec);
-
- byte[][] retByteArray;
-
- r.lock();
- try {
- retByteArray = secp256k1_schnorr_sign(byteBuff, Secp256k1Context.getContext());
- } finally {
- r.unlock();
- }
-
- byte[] sigArr = retByteArray[0];
- int retVal = new BigInteger(new byte[] { retByteArray[1][0] }).intValue();
-
- assertEquals(sigArr.length, 64, "Got bad signature length.");
-
- return retVal == 0 ? new byte[0] : sigArr;
- }
-
- private static native long secp256k1_ctx_clone(long context);
-
- private static native int secp256k1_context_randomize(ByteBuffer byteBuff, long context);
-
- private static native byte[][] secp256k1_privkey_tweak_add(ByteBuffer byteBuff, long context);
-
- private static native byte[][] secp256k1_privkey_tweak_mul(ByteBuffer byteBuff, long context);
-
- private static native byte[][] secp256k1_pubkey_tweak_add(ByteBuffer byteBuff, long context, int pubLen);
-
- private static native byte[][] secp256k1_pubkey_tweak_mul(ByteBuffer byteBuff, long context, int pubLen);
-
- private static native void secp256k1_destroy_context(long context);
-
- private static native int secp256k1_ecdsa_verify(ByteBuffer byteBuff, long context, int sigLen, int pubLen);
-
- private static native byte[][] secp256k1_ecdsa_sign(ByteBuffer byteBuff, long context);
-
- private static native int secp256k1_ec_seckey_verify(ByteBuffer byteBuff, long context);
-
- private static native byte[][] secp256k1_ec_pubkey_create(ByteBuffer byteBuff, long context);
-
- private static native byte[][] secp256k1_ec_pubkey_parse(ByteBuffer byteBuff, long context, int inputLen);
-
- private static native byte[][] secp256k1_schnorr_sign(ByteBuffer byteBuff, long context);
-
- private static native byte[][] secp256k1_ecdh(ByteBuffer byteBuff, long context, int inputLen);
-}
diff --git a/core/src/main/java/org/bitcoin/NativeSecp256k1Util.java b/core/src/main/java/org/bitcoin/NativeSecp256k1Util.java
deleted file mode 100644
index c32f1770b8a..00000000000
--- a/core/src/main/java/org/bitcoin/NativeSecp256k1Util.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright 2014-2016 the libsecp256k1 contributors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.bitcoin;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class NativeSecp256k1Util {
-
- private static final Logger log = LoggerFactory.getLogger(NativeSecp256k1Util.class);
-
- public static void assertEquals(int val, int val2, String message) throws AssertFailException {
- if (val != val2)
- throw new AssertFailException("FAIL: " + message);
- }
-
- public static void assertEquals(boolean val, boolean val2, String message) throws AssertFailException {
- if (val != val2)
- throw new AssertFailException("FAIL: " + message);
- else
- log.debug("PASS: " + message);
- }
-
- public static void assertEquals(String val, String val2, String message) throws AssertFailException {
- if (!val.equals(val2))
- throw new AssertFailException("FAIL: " + message);
- else
- log.debug("PASS: " + message);
- }
-
- public static class AssertFailException extends Exception {
- public AssertFailException(String message) {
- super(message);
- }
- }
-}
diff --git a/core/src/main/java/org/bitcoin/Secp256k1Context.java b/core/src/main/java/org/bitcoin/Secp256k1Context.java
deleted file mode 100644
index f545f7c64bd..00000000000
--- a/core/src/main/java/org/bitcoin/Secp256k1Context.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright 2014-2016 the libsecp256k1 contributors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.bitcoin;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.security.AccessControlException;
-
-/**
- * This class holds the context reference used in native methods to handle ECDSA operations.
- */
-public class Secp256k1Context {
-
- private static final boolean enabled; // true if the library is loaded
- private static final long context; // ref to pointer to context obj
-
- private static final Logger log = LoggerFactory.getLogger(Secp256k1Context.class);
-
- static { // static initializer
- boolean isEnabled = true;
- long contextRef = -1;
- try {
- System.loadLibrary("secp256k1");
- contextRef = secp256k1_init_context();
- } catch (UnsatisfiedLinkError | AccessControlException e) {
- log.debug(e.toString());
- isEnabled = false;
- }
- enabled = isEnabled;
- context = contextRef;
- }
-
- public static boolean isEnabled() {
- return enabled;
- }
-
- public static long getContext() {
- if (!enabled)
- return -1; // sanity check
- return context;
- }
-
- private static native long secp256k1_init_context();
-}
diff --git a/core/src/main/java/org/bitcoinj/core/ECKey.java b/core/src/main/java/org/bitcoinj/core/ECKey.java
index 926936e36a0..b5f3d1239c8 100644
--- a/core/src/main/java/org/bitcoinj/core/ECKey.java
+++ b/core/src/main/java/org/bitcoinj/core/ECKey.java
@@ -18,6 +18,9 @@
package org.bitcoinj.core;
+import org.bitcoin.NativeSecp256k1;
+import org.bitcoin.NativeSecp256k1Exception;
+import org.bitcoin.Secp256k1Context;
import org.bitcoinj.crypto.*;
import org.bitcoinj.script.Script;
@@ -26,9 +29,6 @@
import com.google.common.base.Objects;
import com.google.common.base.Preconditions;
import com.google.common.primitives.UnsignedBytes;
-import org.bitcoin.NativeSecp256k1;
-import org.bitcoin.NativeSecp256k1Util;
-import org.bitcoin.Secp256k1Context;
import org.bitcoinj.wallet.Protos;
import org.bitcoinj.wallet.Wallet;
import org.slf4j.Logger;
@@ -97,7 +97,9 @@
public class ECKey implements EncryptableItem {
private static final Logger log = LoggerFactory.getLogger(ECKey.class);
- /** Sorts oldest keys first, newest last. */
+ /**
+ * Sorts oldest keys first, newest last.
+ */
public static final Comparator AGE_COMPARATOR = new Comparator() {
@Override
@@ -109,7 +111,9 @@ public int compare(ECKey k1, ECKey k2) {
}
};
- /** Compares pub key bytes using {@link com.google.common.primitives.UnsignedBytes#lexicographicalComparator()} */
+ /**
+ * Compares pub key bytes using {@link com.google.common.primitives.UnsignedBytes#lexicographicalComparator()}
+ */
public static final Comparator PUBKEY_COMPARATOR = new Comparator() {
private Comparator comparator = UnsignedBytes.lexicographicalComparator();
@@ -122,7 +126,9 @@ public int compare(ECKey k1, ECKey k2) {
// The parameters of the secp256k1 curve that Bitcoin uses.
private static final X9ECParameters CURVE_PARAMS = CustomNamedCurves.getByName("secp256k1");
- /** The parameters of the secp256k1 curve that Bitcoin uses. */
+ /**
+ * The parameters of the secp256k1 curve that Bitcoin uses.
+ */
public static final ECDomainParameters CURVE;
/**
@@ -148,7 +154,8 @@ public int compare(ECKey k1, ECKey k2) {
// The two parts of the key. If "priv" is set, "pub" can always be calculated. If "pub" is set but not "priv", we
// can only verify signatures not make them.
- @Nullable protected final BigInteger priv; // A field element.
+ @Nullable
+ protected final BigInteger priv; // A field element.
protected final LazyECPoint pub;
// Creation time of the key in seconds since the epoch, or zero if the key was deserialized from a version that did
@@ -226,12 +233,12 @@ public static LazyECPoint decompressPoint(LazyECPoint point) {
}
private static ECPoint getPointWithCompression(ECPoint point, boolean compressed) {
- if (point.isCompressed() == compressed)
- return point;
- point = point.normalize();
- BigInteger x = point.getAffineXCoord().toBigInteger();
- BigInteger y = point.getAffineYCoord().toBigInteger();
- return CURVE.getCurve().createPoint(x, y, compressed);
+ if (point.isCompressed() == compressed)
+ return point;
+ point = point.normalize();
+ BigInteger x = point.getAffineXCoord().toBigInteger();
+ BigInteger y = point.getAffineYCoord().toBigInteger();
+ return CURVE.getCurve().createPoint(x, y, compressed);
}
/**
@@ -336,12 +343,12 @@ public ECKey(@Nullable byte[] privKeyBytes, @Nullable byte[] pubKey) {
* Create a new ECKey with an encrypted private key, a public key and a KeyCrypter.
*
* @param encryptedPrivateKey The private key, encrypted,
- * @param pubKey The keys public key
- * @param keyCrypter The KeyCrypter that will be used, with an AES key, to encrypt and decrypt the private key
+ * @param pubKey The keys public key
+ * @param keyCrypter The KeyCrypter that will be used, with an AES key, to encrypt and decrypt the private key
*/
@Deprecated
public ECKey(EncryptedData encryptedPrivateKey, byte[] pubKey, KeyCrypter keyCrypter) {
- this((byte[])null, pubKey);
+ this((byte[]) null, pubKey);
this.keyCrypter = checkNotNull(keyCrypter);
this.encryptedPrivateKey = encryptedPrivateKey;
@@ -364,6 +371,7 @@ public static ECKey fromEncrypted(EncryptedData encryptedPrivateKey, KeyCrypter
* is supplied, the public key will be calculated from it (this is slow). If both are supplied, it's assumed
* the public key already correctly matches the private key. If only the public key is supplied, this ECKey cannot
* be used for signing.
+ *
* @param compressed If set to true and pubKey is null, the derived public key will be in compressed form.
*/
@Deprecated
@@ -412,7 +420,9 @@ public boolean hasPrivKey() {
return priv != null;
}
- /** Returns true if this key is watch only, meaning it has a public key but no private key. */
+ /**
+ * Returns true if this key is watch only, meaning it has a public key but no private key.
+ */
public boolean isWatching() {
return isPubKeyOnly() && !isEncrypted();
}
@@ -420,6 +430,7 @@ public boolean isWatching() {
/**
* Output this ECKey as an ASN.1 encoded private key, as understood by OpenSSL or used by Bitcoin Core
* in its wallet storage format.
+ *
* @throws org.bitcoinj.core.ECKey.MissingPrivateKeyException if the private key is missing or encrypted.
*/
public byte[] toASN1() {
@@ -469,7 +480,9 @@ public static ECPoint publicPointFromPrivate(BigInteger privKey) {
return new FixedPointCombMultiplier().multiply(CURVE.getG(), privKey);
}
- /** Gets the hash160 form of the public key (as seen in addresses). */
+ /**
+ * Gets the hash160 form of the public key (as seen in addresses).
+ */
public byte[] getPubKeyHash() {
if (pubKeyHash == null)
pubKeyHash = Utils.sha256hash160(this.pub.getEncoded());
@@ -484,7 +497,9 @@ public byte[] getPubKey() {
return pub.getEncoded();
}
- /** Gets the public key in the form of an elliptic curve point object from Bouncy Castle. */
+ /**
+ * Gets the public key in the form of an elliptic curve point object from Bouncy Castle.
+ */
public ECPoint getPubKeyPoint() {
return pub.get();
}
@@ -514,7 +529,9 @@ public boolean isCompressed() {
* components can be useful for doing further EC maths on them.
*/
public static class ECDSASignature {
- /** The two components of the signature. */
+ /**
+ * The two components of the signature.
+ */
public final BigInteger r, s;
/**
@@ -596,7 +613,10 @@ public static ECDSASignature decodeFromDER(byte[] bytes) throws SignatureDecodeE
throw new SignatureDecodeException(e);
} finally {
if (decoder != null)
- try { decoder.close(); } catch (IOException x) {}
+ try {
+ decoder.close();
+ } catch (IOException x) {
+ }
Properties.removeThreadOverride("org.bouncycastle.asn1.allow_unsafe_integer");
}
}
@@ -630,6 +650,7 @@ public int hashCode() {
* usually encoded using ASN.1 format, so you want {@link ECKey.ECDSASignature#toASN1()}
* instead. However sometimes the independent components can be useful, for instance, if you're going to do
* further EC maths on them.
+ *
* @throws KeyCrypterException if this ECKey doesn't have a private part.
*/
public ECDSASignature sign(Sha256Hash input) throws KeyCrypterException {
@@ -651,7 +672,7 @@ public ECDSASignature sign(Sha256Hash input) throws KeyCrypterException {
* EC maths on them.
*
* @param aesKey The AES key to use for decryption of the private key. If null then no decryption is required.
- * @throws KeyCrypterException if there's something wrong with aesKey.
+ * @throws KeyCrypterException if there's something wrong with aesKey.
* @throws ECKey.MissingPrivateKeyException if this key cannot sign because it's pubkey only.
*/
public ECDSASignature sign(Sha256Hash input, @Nullable KeyParameter aesKey) throws KeyCrypterException {
@@ -676,7 +697,7 @@ protected ECDSASignature doSign(Sha256Hash input, BigInteger privateKeyForSignin
Utils.bigIntegerToBytes(privateKeyForSigning, 32)
);
return ECDSASignature.decodeFromDER(signature);
- } catch (NativeSecp256k1Util.AssertFailException e) {
+ } catch (NativeSecp256k1Exception e) {
log.error("Caught AssertFailException inside secp256k1", e);
throw new RuntimeException(e);
} catch (SignatureDecodeException e) {
@@ -695,7 +716,7 @@ protected ECDSASignature doSign(Sha256Hash input, BigInteger privateKeyForSignin
/**
* Verifies the given ECDSA signature against the message bytes using the public key bytes.
- *
+ *
* When using native ECDSA verification, data must be 32 bytes, and no element may be
* larger than 520 bytes.
*
@@ -710,8 +731,8 @@ public static boolean verify(byte[] data, ECDSASignature signature, byte[] pub)
if (Secp256k1Context.isEnabled()) {
try {
return NativeSecp256k1.verify(data, signature.encodeToDER(), pub);
- } catch (NativeSecp256k1Util.AssertFailException e) {
- log.error("Caught AssertFailException inside secp256k1", e);
+ } catch (Exception e) {
+ log.error("Caught Exception inside secp256k1", e);
return false;
}
}
@@ -741,8 +762,8 @@ public static boolean verify(byte[] data, byte[] signature, byte[] pub) throws S
if (Secp256k1Context.isEnabled()) {
try {
return NativeSecp256k1.verify(data, signature, pub);
- } catch (NativeSecp256k1Util.AssertFailException e) {
- log.error("Caught AssertFailException inside secp256k1", e);
+ } catch (Exception e) {
+ log.error("Caught Exception inside secp256k1", e);
return false;
}
}
@@ -770,7 +791,8 @@ public boolean verify(Sha256Hash sigHash, ECDSASignature signature) {
/**
* Verifies the given ASN.1 encoded ECDSA signature against a hash using the public key, and throws an exception
* if the signature doesn't match
- * @throws SignatureDecodeException if the signature is unparseable in some way.
+ *
+ * @throws SignatureDecodeException if the signature is unparseable in some way.
* @throws java.security.SignatureException if the signature does not match.
*/
public void verifyOrThrow(byte[] hash, byte[] signature) throws SignatureDecodeException, SignatureException {
@@ -781,6 +803,7 @@ public void verifyOrThrow(byte[] hash, byte[] signature) throws SignatureDecodeE
/**
* Verifies the given R/S pair (signature) against a hash using the public key, and throws an exception
* if the signature doesn't match
+ *
* @throws java.security.SignatureException if the signature does not match.
*/
public void verifyOrThrow(Sha256Hash sigHash, ECDSASignature signature) throws SignatureException {
@@ -834,7 +857,7 @@ private static ECKey extractKeyFromASN1(byte[] asn1privkey) {
ASN1TaggedObject pubkey = (ASN1TaggedObject) seq.getObjectAt(3);
checkArgument(pubkey.getTagNo() == 1, "Input has 'publicKey' with bad tag number");
- byte[] pubbits = ((DERBitString)pubkey.getObject()).getBytes();
+ byte[] pubbits = ((DERBitString) pubkey.getObject()).getBytes();
checkArgument(pubbits.length == 33 || pubbits.length == 65, "Input has 'publicKey' with invalid length");
int encoding = pubbits[0] & 0xFF;
// Only allow compressed(2,3) and uncompressed(4), not infinity(0) or hybrid(6,7)
@@ -856,7 +879,7 @@ private static ECKey extractKeyFromASN1(byte[] asn1privkey) {
* encoded string.
*
* @throws IllegalStateException if this ECKey does not have the private part.
- * @throws KeyCrypterException if this ECKey is encrypted and no AESKey is provided or it does not decrypt the ECKey.
+ * @throws KeyCrypterException if this ECKey is encrypted and no AESKey is provided or it does not decrypt the ECKey.
*/
public String signMessage(String message) throws KeyCrypterException {
return signMessage(message, null);
@@ -867,7 +890,7 @@ public String signMessage(String message) throws KeyCrypterException {
* encoded string.
*
* @throws IllegalStateException if this ECKey does not have the private part.
- * @throws KeyCrypterException if this ECKey is encrypted and no AESKey is provided or it does not decrypt the ECKey.
+ * @throws KeyCrypterException if this ECKey is encrypted and no AESKey is provided or it does not decrypt the ECKey.
*/
public String signMessage(String message, @Nullable KeyParameter aesKey) throws KeyCrypterException {
byte[] data = formatMessageForSigning(message);
@@ -876,7 +899,7 @@ public String signMessage(String message, @Nullable KeyParameter aesKey) throws
byte recId = findRecoveryId(hash, sig);
int headerByte = recId + 27 + (isCompressed() ? 4 : 0);
byte[] sigData = new byte[65]; // 1 header + 32 bytes for R + 32 bytes for S
- sigData[0] = (byte)headerByte;
+ sigData[0] = (byte) headerByte;
System.arraycopy(Utils.bigIntegerToBytes(sig.r, 32), 0, sigData, 1, 32);
System.arraycopy(Utils.bigIntegerToBytes(sig.s, 32), 0, sigData, 33, 32);
return new String(Base64.encode(sigData), StandardCharsets.UTF_8);
@@ -889,7 +912,7 @@ public String signMessage(String message, @Nullable KeyParameter aesKey) throws
* format generated by signmessage/verifymessage RPCs and GUI menu options. They are intended for humans to verify
* their communications with each other, hence the base64 format and the fact that the input is text.
*
- * @param message Some piece of human readable text.
+ * @param message Some piece of human readable text.
* @param signatureBase64 The Bitcoin-format message signature in base64
* @throws SignatureException If the public key could not be recovered or if there was a signature format error.
*/
@@ -972,9 +995,9 @@ public byte findRecoveryId(Sha256Hash hash, ECDSASignature sig) {
* Given the above two points, a correct usage of this method is inside a for loop from 0 to 3, and if the
* output is null OR a key that is not the one you expect, you try again with the next recId.
*
- * @param recId Which possible key to recover.
- * @param sig the R and S components of the signature, wrapped.
- * @param message Hash of the data that was signed.
+ * @param recId Which possible key to recover.
+ * @param sig the R and S components of the signature, wrapped.
+ * @param message Hash of the data that was signed.
* @param compressed Whether or not the original pubkey was compressed.
* @return An ECKey containing only the public part, or null if recovery wasn't possible.
*/
@@ -1028,16 +1051,19 @@ public static ECKey recoverFromSignature(int recId, ECDSASignature sig, Sha256Ha
return ECKey.fromPublicOnly(q.getEncoded(compressed));
}
- /** Decompress a compressed public key (x co-ord and low-bit of y-coord). */
+ /**
+ * Decompress a compressed public key (x co-ord and low-bit of y-coord).
+ */
private static ECPoint decompressKey(BigInteger xBN, boolean yBit) {
X9IntegerConverter x9 = new X9IntegerConverter();
byte[] compEnc = x9.integerToBytes(xBN, 1 + x9.getByteLength(CURVE.getCurve()));
- compEnc[0] = (byte)(yBit ? 0x03 : 0x02);
+ compEnc[0] = (byte) (yBit ? 0x03 : 0x02);
return CURVE.getCurve().decodePoint(compEnc);
}
/**
* Returns a 32 byte array containing the private key.
+ *
* @throws org.bitcoinj.core.ECKey.MissingPrivateKeyException if the private key bytes are missing/encrypted.
*/
public byte[] getPrivKeyBytes() {
@@ -1080,7 +1106,7 @@ public void setCreationTimeSeconds(long newCreationTimeSeconds) {
* This method returns a new encrypted key and leaves the original unchanged.
*
* @param keyCrypter The keyCrypter that specifies exactly how the encrypted bytes are created.
- * @param aesKey The KeyParameter with the AES encryption key (usually constructed with keyCrypter#deriveKey and cached as it is slow to create).
+ * @param aesKey The KeyParameter with the AES encryption key (usually constructed with keyCrypter#deriveKey and cached as it is slow to create).
* @return encryptedKey
*/
public ECKey encrypt(KeyCrypter keyCrypter, KeyParameter aesKey) throws KeyCrypterException {
@@ -1098,7 +1124,7 @@ public ECKey encrypt(KeyCrypter keyCrypter, KeyParameter aesKey) throws KeyCrypt
* just yield a garbage key.
*
* @param keyCrypter The keyCrypter that specifies exactly how the decrypted bytes are created.
- * @param aesKey The KeyParameter with the AES encryption key (usually constructed with keyCrypter#deriveKey and cached).
+ * @param aesKey The KeyParameter with the AES encryption key (usually constructed with keyCrypter#deriveKey and cached).
*/
public ECKey decrypt(KeyCrypter keyCrypter, KeyParameter aesKey) throws KeyCrypterException {
checkNotNull(keyCrypter);
@@ -1195,7 +1221,9 @@ public byte[] getSecretBytes() {
return null;
}
- /** An alias for {@link #getEncryptedPrivateKey()} */
+ /**
+ * An alias for {@link #getEncryptedPrivateKey()}
+ */
@Nullable
@Override
public EncryptedData getEncryptedData() {
@@ -1293,7 +1321,7 @@ private String toString(boolean includePrivate, @Nullable KeyParameter aesKey, @
}
public void formatKeyWithAddress(boolean includePrivateKeys, @Nullable KeyParameter aesKey, StringBuilder builder,
- NetworkParameters params, Script.ScriptType outputScriptType, @Nullable String comment) {
+ NetworkParameters params, Script.ScriptType outputScriptType, @Nullable String comment) {
builder.append(" addr:");
if (outputScriptType != null) {
builder.append(Address.fromKey(params, this, outputScriptType));
@@ -1319,7 +1347,9 @@ public void formatKeyWithAddress(boolean includePrivateKeys, @Nullable KeyParame
}
}
- /** The string that prefixes all text messages signed using Bitcoin keys. */
+ /**
+ * The string that prefixes all text messages signed using Bitcoin keys.
+ */
private static final String BITCOIN_SIGNED_MESSAGE_HEADER = "Bitcoin Signed Message:\n";
private static final byte[] BITCOIN_SIGNED_MESSAGE_HEADER_BYTES = BITCOIN_SIGNED_MESSAGE_HEADER.getBytes(StandardCharsets.UTF_8);
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index dde2480651f..b4bec8d95ce 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -3,6 +3,6 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-4.7-all.zip
-distributionSha256Sum=203f4537da8b8075e38c036a6d14cb71b1149de5bf0a8f6db32ac2833a1d1294
+distributionUrl=https\://services.gradle.org/distributions/gradle-4.9-all.zip
+distributionSha256Sum=39e2d5803bbd5eaf6c8efe07067b0e5a00235e8c71318642b2ed262920b27721
name=RskJ