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