mirror of
https://github.com/bitcoinj/bitcoinj.git
synced 2024-11-19 01:40:26 +01:00
LazyECPoint: make private curve
member static
We do not need to specify the curve for each instance as bitcoinj uses SECP256K1 curve exclusively. This change reduces per instance memory usage, simplifies the API, and reduces public API dependence on Bouncy Castle. One two-arg constructor is deprecated and replaced with a single-arg constructor that no longer requires the curve parameter. Just to be extra safe, in the deprecated method we validate the curve argument and make sure it is the P256K1 curve. Also correctly mark private `bits` field as @Nullable, and improve JavaDoc and other comments.
This commit is contained in:
parent
155b404063
commit
3a28fb0274
@ -685,7 +685,7 @@ public class DeterministicKey extends ECKey {
|
||||
checkArgument(!buffer.hasRemaining(), () ->
|
||||
"found unexpected data in key");
|
||||
if (pub) {
|
||||
return new DeterministicKey(path, chainCode, new LazyECPoint(ECKey.CURVE.getCurve(), data), parent, depth, parentFingerprint);
|
||||
return new DeterministicKey(path, chainCode, new LazyECPoint(data), parent, depth, parentFingerprint);
|
||||
} else {
|
||||
return new DeterministicKey(path, chainCode, ByteUtils.bytesToBigInteger(data), parent, depth, parentFingerprint);
|
||||
}
|
||||
|
@ -259,7 +259,7 @@ public class ECKey implements EncryptableItem {
|
||||
public static ECKey fromPrivateAndPrecalculatedPublic(byte[] priv, byte[] pub) {
|
||||
Objects.requireNonNull(priv);
|
||||
Objects.requireNonNull(pub);
|
||||
return new ECKey(ByteUtils.bytesToBigInteger(priv), new LazyECPoint(CURVE.getCurve(), pub));
|
||||
return new ECKey(ByteUtils.bytesToBigInteger(priv), new LazyECPoint(pub));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -275,7 +275,7 @@ public class ECKey implements EncryptableItem {
|
||||
* The compression state of pub will be preserved.
|
||||
*/
|
||||
public static ECKey fromPublicOnly(byte[] pub) {
|
||||
return new ECKey(null, new LazyECPoint(CURVE.getCurve(), pub));
|
||||
return new ECKey(null, new LazyECPoint(pub));
|
||||
}
|
||||
|
||||
public static ECKey fromPublicOnly(ECKey key) {
|
||||
|
@ -90,7 +90,7 @@ public final class HDKeyDerivation {
|
||||
}
|
||||
|
||||
public static DeterministicKey createMasterPubKeyFromBytes(byte[] pubKeyBytes, byte[] chainCode) {
|
||||
return new DeterministicKey(HDPath.M(), chainCode, new LazyECPoint(ECKey.CURVE.getCurve(), pubKeyBytes), null, null);
|
||||
return new DeterministicKey(HDPath.M(), chainCode, new LazyECPoint(pubKeyBytes), null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -190,7 +190,7 @@ public final class HDKeyDerivation {
|
||||
PublicDeriveMode mode) throws HDDerivationException {
|
||||
RawKeyBytes rawKey = deriveChildKeyBytesFromPublic(parent, childNumber, PublicDeriveMode.NORMAL);
|
||||
return new DeterministicKey(parent.getPath().extend(childNumber), rawKey.chainCode,
|
||||
new LazyECPoint(ECKey.CURVE.getCurve(), rawKey.keyBytes), null, parent);
|
||||
new LazyECPoint(rawKey.keyBytes), null, parent);
|
||||
}
|
||||
|
||||
public static RawKeyBytes deriveChildKeyBytesFromPublic(DeterministicKey parent, ChildNumber childNumber, PublicDeriveMode mode) throws HDDerivationException {
|
||||
|
@ -25,20 +25,21 @@ import java.math.BigInteger;
|
||||
import java.util.Arrays;
|
||||
import java.util.Objects;
|
||||
|
||||
import static org.bitcoinj.base.internal.Preconditions.checkArgument;
|
||||
|
||||
/**
|
||||
* A wrapper around ECPoint that delays decoding of the point for as long as possible. This is useful because point
|
||||
* A wrapper around a SECP256K1 ECPoint that delays decoding of the point for as long as possible. This is useful because point
|
||||
* encode/decode in Bouncy Castle is quite slow especially on Dalvik, as it often involves decompression/recompression.
|
||||
*/
|
||||
public class LazyECPoint {
|
||||
// If curve is set, bits is also set. If curve is unset, point is set and bits is unset. Point can be set along
|
||||
// with curve and bits when the cached form has been accessed and thus must have been converted.
|
||||
private static final ECCurve curve = ECKey.CURVE.getCurve();
|
||||
|
||||
private final ECCurve curve;
|
||||
// bits will be null if LazyECPoint is constructed from an (already decoded) point
|
||||
@Nullable
|
||||
private final byte[] bits;
|
||||
private final boolean compressed;
|
||||
|
||||
// This field is effectively final - once set it won't change again. However it can be set after
|
||||
// construction.
|
||||
// This field is lazy - once set it won't change again. However, it can be set after construction.
|
||||
@Nullable
|
||||
private ECPoint point;
|
||||
|
||||
@ -46,11 +47,24 @@ public class LazyECPoint {
|
||||
* Construct a LazyECPoint from a public key. Due to the delayed decoding of the point the validation of the
|
||||
* public key is delayed too, e.g. until a getter is called.
|
||||
*
|
||||
* @param curve a curve the point is on
|
||||
* @param bits public key bytes
|
||||
*/
|
||||
public LazyECPoint(byte[] bits) {
|
||||
this.bits = bits;
|
||||
this.compressed = ECKey.isPubKeyCompressed(bits);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a LazyECPoint from a public key. Due to the delayed decoding of the point the validation of the
|
||||
* public key is delayed too, e.g. until a getter is called.
|
||||
*
|
||||
* @param curve a curve the point is on
|
||||
* @param bits public key bytes
|
||||
* @deprecated Use {@link LazyECPoint#LazyECPoint(byte[])}
|
||||
*/
|
||||
@Deprecated
|
||||
public LazyECPoint(ECCurve curve, byte[] bits) {
|
||||
this.curve = curve;
|
||||
checkArgument(LazyECPoint.curve.equals(curve), () -> "Curve must be SECP256K1");
|
||||
this.bits = bits;
|
||||
this.compressed = ECKey.isPubKeyCompressed(bits);
|
||||
}
|
||||
@ -64,7 +78,6 @@ public class LazyECPoint {
|
||||
public LazyECPoint(ECPoint point, boolean compressed) {
|
||||
this.point = Objects.requireNonNull(point).normalize();
|
||||
this.compressed = compressed;
|
||||
this.curve = null;
|
||||
this.bits = null;
|
||||
}
|
||||
|
||||
|
@ -893,7 +893,7 @@ public class DeterministicKeyChain implements EncryptableKeyChain {
|
||||
throw new UnreadableWalletException("Deterministic key missing extra data: " + key);
|
||||
byte[] chainCode = key.getDeterministicKey().getChainCode().toByteArray();
|
||||
// Deserialize the public key and path.
|
||||
LazyECPoint pubkey = new LazyECPoint(ECKey.CURVE.getCurve(), key.getPublicKey().toByteArray());
|
||||
LazyECPoint pubkey = new LazyECPoint(key.getPublicKey().toByteArray());
|
||||
// Deserialize the path through the tree.
|
||||
final HDPath path = HDPath.deserialize(key.getDeterministicKey().getPathList());
|
||||
if (key.hasOutputScriptType())
|
||||
|
Loading…
Reference in New Issue
Block a user