Changeset View
Changeset View
Standalone View
Standalone View
src/secp256k1/src/java/org/bitcoin/NativeSecp256k1.java
Show All 15 Lines | |||||
*/ | */ | ||||
package org.bitcoin; | package org.bitcoin; | ||||
import java.nio.ByteBuffer; | import java.nio.ByteBuffer; | ||||
import java.nio.ByteOrder; | import java.nio.ByteOrder; | ||||
import java.math.BigInteger; | import java.math.BigInteger; | ||||
import com.google.common.base.Preconditions; | |||||
import java.util.concurrent.locks.Lock; | import java.util.concurrent.locks.Lock; | ||||
import java.util.concurrent.locks.ReentrantReadWriteLock; | import java.util.concurrent.locks.ReentrantReadWriteLock; | ||||
import static org.bitcoin.NativeSecp256k1Util.*; | import static org.bitcoin.NativeSecp256k1Util.*; | ||||
/** | /** | ||||
* <p>This class holds native methods to handle ECDSA verification.</p> | * <p>This class holds native methods to handle ECDSA verification.</p> | ||||
* | * | ||||
* <p>You can find an example library that can be used for this at https://github.com/bitcoin/secp256k1</p> | * <p>You can find an example library that can be used for this at https://github.com/bitcoin/secp256k1</p> | ||||
Show All 13 Lines | public class NativeSecp256k1 { | ||||
/** | /** | ||||
* Verifies the given secp256k1 signature in native code. | * Verifies the given secp256k1 signature in native code. | ||||
* Calling when enabled == false is undefined (probably library not loaded) | * Calling when enabled == false is undefined (probably library not loaded) | ||||
* | * | ||||
* @param data The data which was signed, must be exactly 32 bytes | * @param data The data which was signed, must be exactly 32 bytes | ||||
* @param signature The signature | * @param signature The signature | ||||
* @param pub The public key which did the signing | * @param pub The public key which did the signing | ||||
*/ | */ | ||||
public static boolean verify(byte[] data, byte[] signature, byte[] pub) throws AssertFailException{ | public static boolean verify(byte[] data, byte[] signature, byte[] pub) { | ||||
Preconditions.checkArgument(data.length == 32 && signature.length <= 520 && pub.length <= 520); | checkArgument(data.length == 32 && signature.length <= 520 && pub.length <= 520); | ||||
ByteBuffer byteBuff = nativeECDSABuffer.get(); | ByteBuffer byteBuff = nativeECDSABuffer.get(); | ||||
if (byteBuff == null || byteBuff.capacity() < 520) { | if (byteBuff == null || byteBuff.capacity() < 520) { | ||||
byteBuff = ByteBuffer.allocateDirect(520); | byteBuff = ByteBuffer.allocateDirect(520); | ||||
byteBuff.order(ByteOrder.nativeOrder()); | byteBuff.order(ByteOrder.nativeOrder()); | ||||
nativeECDSABuffer.set(byteBuff); | nativeECDSABuffer.set(byteBuff); | ||||
} | } | ||||
byteBuff.rewind(); | byteBuff.rewind(); | ||||
Show All 16 Lines | public class NativeSecp256k1 { | ||||
* | * | ||||
* @param data Message hash, 32 bytes | * @param data Message hash, 32 bytes | ||||
* @param key Secret key, 32 bytes | * @param key Secret key, 32 bytes | ||||
* | * | ||||
* Return values | * Return values | ||||
* @param sig byte array of signature | * @param sig byte array of signature | ||||
*/ | */ | ||||
public static byte[] sign(byte[] data, byte[] sec) throws AssertFailException{ | public static byte[] sign(byte[] data, byte[] sec) throws AssertFailException{ | ||||
Preconditions.checkArgument(data.length == 32 && sec.length <= 32); | checkArgument(data.length == 32 && sec.length <= 32); | ||||
ByteBuffer byteBuff = nativeECDSABuffer.get(); | ByteBuffer byteBuff = nativeECDSABuffer.get(); | ||||
if (byteBuff == null || byteBuff.capacity() < 32 + 32) { | if (byteBuff == null || byteBuff.capacity() < 32 + 32) { | ||||
byteBuff = ByteBuffer.allocateDirect(32 + 32); | byteBuff = ByteBuffer.allocateDirect(32 + 32); | ||||
byteBuff.order(ByteOrder.nativeOrder()); | byteBuff.order(ByteOrder.nativeOrder()); | ||||
nativeECDSABuffer.set(byteBuff); | nativeECDSABuffer.set(byteBuff); | ||||
} | } | ||||
byteBuff.rewind(); | byteBuff.rewind(); | ||||
Show All 19 Lines | public class NativeSecp256k1 { | ||||
} | } | ||||
/** | /** | ||||
* libsecp256k1 Seckey Verify - returns 1 if valid, 0 if invalid | * libsecp256k1 Seckey Verify - returns 1 if valid, 0 if invalid | ||||
* | * | ||||
* @param seckey ECDSA Secret key, 32 bytes | * @param seckey ECDSA Secret key, 32 bytes | ||||
*/ | */ | ||||
public static boolean secKeyVerify(byte[] seckey) { | public static boolean secKeyVerify(byte[] seckey) { | ||||
Preconditions.checkArgument(seckey.length == 32); | checkArgument(seckey.length == 32); | ||||
ByteBuffer byteBuff = nativeECDSABuffer.get(); | ByteBuffer byteBuff = nativeECDSABuffer.get(); | ||||
if (byteBuff == null || byteBuff.capacity() < seckey.length) { | if (byteBuff == null || byteBuff.capacity() < seckey.length) { | ||||
byteBuff = ByteBuffer.allocateDirect(seckey.length); | byteBuff = ByteBuffer.allocateDirect(seckey.length); | ||||
byteBuff.order(ByteOrder.nativeOrder()); | byteBuff.order(ByteOrder.nativeOrder()); | ||||
nativeECDSABuffer.set(byteBuff); | nativeECDSABuffer.set(byteBuff); | ||||
} | } | ||||
byteBuff.rewind(); | byteBuff.rewind(); | ||||
Show All 13 Lines | public class NativeSecp256k1 { | ||||
* | * | ||||
* @param seckey ECDSA Secret key, 32 bytes | * @param seckey ECDSA Secret key, 32 bytes | ||||
* | * | ||||
* Return values | * Return values | ||||
* @param pubkey ECDSA Public key, 33 or 65 bytes | * @param pubkey ECDSA Public key, 33 or 65 bytes | ||||
*/ | */ | ||||
//TODO add a 'compressed' arg | //TODO add a 'compressed' arg | ||||
public static byte[] computePubkey(byte[] seckey) throws AssertFailException{ | public static byte[] computePubkey(byte[] seckey) throws AssertFailException{ | ||||
Preconditions.checkArgument(seckey.length == 32); | checkArgument(seckey.length == 32); | ||||
ByteBuffer byteBuff = nativeECDSABuffer.get(); | ByteBuffer byteBuff = nativeECDSABuffer.get(); | ||||
if (byteBuff == null || byteBuff.capacity() < seckey.length) { | if (byteBuff == null || byteBuff.capacity() < seckey.length) { | ||||
byteBuff = ByteBuffer.allocateDirect(seckey.length); | byteBuff = ByteBuffer.allocateDirect(seckey.length); | ||||
byteBuff.order(ByteOrder.nativeOrder()); | byteBuff.order(ByteOrder.nativeOrder()); | ||||
nativeECDSABuffer.set(byteBuff); | nativeECDSABuffer.set(byteBuff); | ||||
} | } | ||||
byteBuff.rewind(); | byteBuff.rewind(); | ||||
Show All 39 Lines | public class NativeSecp256k1 { | ||||
/** | /** | ||||
* libsecp256k1 PrivKey Tweak-Mul - Tweak privkey by multiplying to it | * libsecp256k1 PrivKey Tweak-Mul - Tweak privkey by multiplying to it | ||||
* | * | ||||
* @param tweak some bytes to tweak with | * @param tweak some bytes to tweak with | ||||
* @param seckey 32-byte seckey | * @param seckey 32-byte seckey | ||||
*/ | */ | ||||
public static byte[] privKeyTweakMul(byte[] privkey, byte[] tweak) throws AssertFailException{ | public static byte[] privKeyTweakMul(byte[] privkey, byte[] tweak) throws AssertFailException{ | ||||
Preconditions.checkArgument(privkey.length == 32); | checkArgument(privkey.length == 32); | ||||
ByteBuffer byteBuff = nativeECDSABuffer.get(); | ByteBuffer byteBuff = nativeECDSABuffer.get(); | ||||
if (byteBuff == null || byteBuff.capacity() < privkey.length + tweak.length) { | if (byteBuff == null || byteBuff.capacity() < privkey.length + tweak.length) { | ||||
byteBuff = ByteBuffer.allocateDirect(privkey.length + tweak.length); | byteBuff = ByteBuffer.allocateDirect(privkey.length + tweak.length); | ||||
byteBuff.order(ByteOrder.nativeOrder()); | byteBuff.order(ByteOrder.nativeOrder()); | ||||
nativeECDSABuffer.set(byteBuff); | nativeECDSABuffer.set(byteBuff); | ||||
} | } | ||||
byteBuff.rewind(); | byteBuff.rewind(); | ||||
Show All 22 Lines | public class NativeSecp256k1 { | ||||
/** | /** | ||||
* libsecp256k1 PrivKey Tweak-Add - Tweak privkey by adding to it | * libsecp256k1 PrivKey Tweak-Add - Tweak privkey by adding to it | ||||
* | * | ||||
* @param tweak some bytes to tweak with | * @param tweak some bytes to tweak with | ||||
* @param seckey 32-byte seckey | * @param seckey 32-byte seckey | ||||
*/ | */ | ||||
public static byte[] privKeyTweakAdd(byte[] privkey, byte[] tweak) throws AssertFailException{ | public static byte[] privKeyTweakAdd(byte[] privkey, byte[] tweak) throws AssertFailException{ | ||||
Preconditions.checkArgument(privkey.length == 32); | checkArgument(privkey.length == 32); | ||||
ByteBuffer byteBuff = nativeECDSABuffer.get(); | ByteBuffer byteBuff = nativeECDSABuffer.get(); | ||||
if (byteBuff == null || byteBuff.capacity() < privkey.length + tweak.length) { | if (byteBuff == null || byteBuff.capacity() < privkey.length + tweak.length) { | ||||
byteBuff = ByteBuffer.allocateDirect(privkey.length + tweak.length); | byteBuff = ByteBuffer.allocateDirect(privkey.length + tweak.length); | ||||
byteBuff.order(ByteOrder.nativeOrder()); | byteBuff.order(ByteOrder.nativeOrder()); | ||||
nativeECDSABuffer.set(byteBuff); | nativeECDSABuffer.set(byteBuff); | ||||
} | } | ||||
byteBuff.rewind(); | byteBuff.rewind(); | ||||
Show All 22 Lines | public class NativeSecp256k1 { | ||||
/** | /** | ||||
* libsecp256k1 PubKey Tweak-Add - Tweak pubkey by adding to it | * libsecp256k1 PubKey Tweak-Add - Tweak pubkey by adding to it | ||||
* | * | ||||
* @param tweak some bytes to tweak with | * @param tweak some bytes to tweak with | ||||
* @param pubkey 32-byte seckey | * @param pubkey 32-byte seckey | ||||
*/ | */ | ||||
public static byte[] pubKeyTweakAdd(byte[] pubkey, byte[] tweak) throws AssertFailException{ | public static byte[] pubKeyTweakAdd(byte[] pubkey, byte[] tweak) throws AssertFailException{ | ||||
Preconditions.checkArgument(pubkey.length == 33 || pubkey.length == 65); | checkArgument(pubkey.length == 33 || pubkey.length == 65); | ||||
ByteBuffer byteBuff = nativeECDSABuffer.get(); | ByteBuffer byteBuff = nativeECDSABuffer.get(); | ||||
if (byteBuff == null || byteBuff.capacity() < pubkey.length + tweak.length) { | if (byteBuff == null || byteBuff.capacity() < pubkey.length + tweak.length) { | ||||
byteBuff = ByteBuffer.allocateDirect(pubkey.length + tweak.length); | byteBuff = ByteBuffer.allocateDirect(pubkey.length + tweak.length); | ||||
byteBuff.order(ByteOrder.nativeOrder()); | byteBuff.order(ByteOrder.nativeOrder()); | ||||
nativeECDSABuffer.set(byteBuff); | nativeECDSABuffer.set(byteBuff); | ||||
} | } | ||||
byteBuff.rewind(); | byteBuff.rewind(); | ||||
Show All 22 Lines | public class NativeSecp256k1 { | ||||
/** | /** | ||||
* libsecp256k1 PubKey Tweak-Mul - Tweak pubkey by multiplying to it | * libsecp256k1 PubKey Tweak-Mul - Tweak pubkey by multiplying to it | ||||
* | * | ||||
* @param tweak some bytes to tweak with | * @param tweak some bytes to tweak with | ||||
* @param pubkey 32-byte seckey | * @param pubkey 32-byte seckey | ||||
*/ | */ | ||||
public static byte[] pubKeyTweakMul(byte[] pubkey, byte[] tweak) throws AssertFailException{ | public static byte[] pubKeyTweakMul(byte[] pubkey, byte[] tweak) throws AssertFailException{ | ||||
Preconditions.checkArgument(pubkey.length == 33 || pubkey.length == 65); | checkArgument(pubkey.length == 33 || pubkey.length == 65); | ||||
ByteBuffer byteBuff = nativeECDSABuffer.get(); | ByteBuffer byteBuff = nativeECDSABuffer.get(); | ||||
if (byteBuff == null || byteBuff.capacity() < pubkey.length + tweak.length) { | if (byteBuff == null || byteBuff.capacity() < pubkey.length + tweak.length) { | ||||
byteBuff = ByteBuffer.allocateDirect(pubkey.length + tweak.length); | byteBuff = ByteBuffer.allocateDirect(pubkey.length + tweak.length); | ||||
byteBuff.order(ByteOrder.nativeOrder()); | byteBuff.order(ByteOrder.nativeOrder()); | ||||
nativeECDSABuffer.set(byteBuff); | nativeECDSABuffer.set(byteBuff); | ||||
} | } | ||||
byteBuff.rewind(); | byteBuff.rewind(); | ||||
Show All 22 Lines | public class NativeSecp256k1 { | ||||
/** | /** | ||||
* libsecp256k1 create ECDH secret - constant time ECDH calculation | * libsecp256k1 create ECDH secret - constant time ECDH calculation | ||||
* | * | ||||
* @param seckey byte array of secret key used in exponentiaion | * @param seckey byte array of secret key used in exponentiaion | ||||
* @param pubkey byte array of public key used in exponentiaion | * @param pubkey byte array of public key used in exponentiaion | ||||
*/ | */ | ||||
public static byte[] createECDHSecret(byte[] seckey, byte[] pubkey) throws AssertFailException{ | public static byte[] createECDHSecret(byte[] seckey, byte[] pubkey) throws AssertFailException{ | ||||
Preconditions.checkArgument(seckey.length <= 32 && pubkey.length <= 65); | checkArgument(seckey.length <= 32 && pubkey.length <= 65); | ||||
ByteBuffer byteBuff = nativeECDSABuffer.get(); | ByteBuffer byteBuff = nativeECDSABuffer.get(); | ||||
if (byteBuff == null || byteBuff.capacity() < 32 + pubkey.length) { | if (byteBuff == null || byteBuff.capacity() < 32 + pubkey.length) { | ||||
byteBuff = ByteBuffer.allocateDirect(32 + pubkey.length); | byteBuff = ByteBuffer.allocateDirect(32 + pubkey.length); | ||||
byteBuff.order(ByteOrder.nativeOrder()); | byteBuff.order(ByteOrder.nativeOrder()); | ||||
nativeECDSABuffer.set(byteBuff); | nativeECDSABuffer.set(byteBuff); | ||||
} | } | ||||
byteBuff.rewind(); | byteBuff.rewind(); | ||||
Show All 18 Lines | public class NativeSecp256k1 { | ||||
} | } | ||||
/** | /** | ||||
* libsecp256k1 randomize - updates the context randomization | * libsecp256k1 randomize - updates the context randomization | ||||
* | * | ||||
* @param seed 32-byte random seed | * @param seed 32-byte random seed | ||||
*/ | */ | ||||
public static synchronized boolean randomize(byte[] seed) throws AssertFailException{ | public static synchronized boolean randomize(byte[] seed) throws AssertFailException{ | ||||
Preconditions.checkArgument(seed.length == 32 || seed == null); | checkArgument(seed.length == 32 || seed == null); | ||||
ByteBuffer byteBuff = nativeECDSABuffer.get(); | ByteBuffer byteBuff = nativeECDSABuffer.get(); | ||||
if (byteBuff == null || byteBuff.capacity() < seed.length) { | if (byteBuff == null || byteBuff.capacity() < seed.length) { | ||||
byteBuff = ByteBuffer.allocateDirect(seed.length); | byteBuff = ByteBuffer.allocateDirect(seed.length); | ||||
byteBuff.order(ByteOrder.nativeOrder()); | byteBuff.order(ByteOrder.nativeOrder()); | ||||
nativeECDSABuffer.set(byteBuff); | nativeECDSABuffer.set(byteBuff); | ||||
} | } | ||||
byteBuff.rewind(); | byteBuff.rewind(); | ||||
Show All 37 Lines |