mirror of
https://github.com/bitcoinj/bitcoinj.git
synced 2025-02-23 22:46:56 +01:00
Track point compression in LazyECPoint, rather than ECPoint.
The reason is BouncyCastle 1.64 removed point compression tracking.
This commit is contained in:
parent
7eb9c73655
commit
7629677103
9 changed files with 62 additions and 75 deletions
|
@ -63,9 +63,6 @@ import java.util.Objects;
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.*;
|
import static com.google.common.base.Preconditions.*;
|
||||||
|
|
||||||
// TODO: Move this class to tracking compression state itself.
|
|
||||||
// The Bouncy Castle developers are deprecating their own tracking of the compression state.
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>Represents an elliptic curve public and (optionally) private key, usable for digital signatures but not encryption.
|
* <p>Represents an elliptic curve public and (optionally) private key, usable for digital signatures but not encryption.
|
||||||
* Creating a new ECKey with the empty constructor will generate a new random keypair. Other static methods can be used
|
* Creating a new ECKey with the empty constructor will generate a new random keypair. Other static methods can be used
|
||||||
|
@ -179,12 +176,12 @@ public class ECKey implements EncryptableItem {
|
||||||
ECPrivateKeyParameters privParams = (ECPrivateKeyParameters) keypair.getPrivate();
|
ECPrivateKeyParameters privParams = (ECPrivateKeyParameters) keypair.getPrivate();
|
||||||
ECPublicKeyParameters pubParams = (ECPublicKeyParameters) keypair.getPublic();
|
ECPublicKeyParameters pubParams = (ECPublicKeyParameters) keypair.getPublic();
|
||||||
priv = privParams.getD();
|
priv = privParams.getD();
|
||||||
pub = new LazyECPoint(CURVE.getCurve(), pubParams.getQ().getEncoded(true));
|
pub = getPointWithCompression(pubParams.getQ(), true);
|
||||||
creationTimeSeconds = Utils.currentTimeSeconds();
|
creationTimeSeconds = Utils.currentTimeSeconds();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected ECKey(@Nullable BigInteger priv, ECPoint pub) {
|
protected ECKey(@Nullable BigInteger priv, ECPoint pub, boolean compressed) {
|
||||||
this(priv, new LazyECPoint(checkNotNull(pub)));
|
this(priv, getPointWithCompression(checkNotNull(pub), compressed));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected ECKey(@Nullable BigInteger priv, LazyECPoint pub) {
|
protected ECKey(@Nullable BigInteger priv, LazyECPoint pub) {
|
||||||
|
@ -204,33 +201,20 @@ public class ECKey implements EncryptableItem {
|
||||||
* Utility for compressing an elliptic curve point. Returns the same point if it's already compressed.
|
* Utility for compressing an elliptic curve point. Returns the same point if it's already compressed.
|
||||||
* See the ECKey class docs for a discussion of point compression.
|
* See the ECKey class docs for a discussion of point compression.
|
||||||
*/
|
*/
|
||||||
public static ECPoint compressPoint(ECPoint point) {
|
|
||||||
return getPointWithCompression(point, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static LazyECPoint compressPoint(LazyECPoint point) {
|
public static LazyECPoint compressPoint(LazyECPoint point) {
|
||||||
return point.isCompressed() ? point : new LazyECPoint(compressPoint(point.get()));
|
return point.isCompressed() ? point : getPointWithCompression(point.get(), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Utility for decompressing an elliptic curve point. Returns the same point if it's already compressed.
|
* Utility for decompressing an elliptic curve point. Returns the same point if it's already uncompressed.
|
||||||
* See the ECKey class docs for a discussion of point compression.
|
* See the ECKey class docs for a discussion of point compression.
|
||||||
*/
|
*/
|
||||||
public static ECPoint decompressPoint(ECPoint point) {
|
|
||||||
return getPointWithCompression(point, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static LazyECPoint decompressPoint(LazyECPoint point) {
|
public static LazyECPoint decompressPoint(LazyECPoint point) {
|
||||||
return !point.isCompressed() ? point : new LazyECPoint(decompressPoint(point.get()));
|
return !point.isCompressed() ? point : getPointWithCompression(point.get(), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ECPoint getPointWithCompression(ECPoint point, boolean compressed) {
|
private static LazyECPoint getPointWithCompression(ECPoint point, boolean compressed) {
|
||||||
if (point.isCompressed() == compressed)
|
return new LazyECPoint(point, compressed);
|
||||||
return point;
|
|
||||||
point = point.normalize();
|
|
||||||
BigInteger x = point.getAffineXCoord().toBigInteger();
|
|
||||||
BigInteger y = point.getAffineYCoord().toBigInteger();
|
|
||||||
return CURVE.getCurve().createPoint(x, y, compressed);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -250,8 +234,8 @@ public class ECKey implements EncryptableItem {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates an ECKey given the private key only. The public key is calculated from it (this is slow), either
|
* Creates an ECKey given the private key only. The public key is calculated from it (this is slow).
|
||||||
* compressed or not.
|
* @param compressed Determines whether the resulting ECKey will use a compressed encoding for the public key.
|
||||||
*/
|
*/
|
||||||
public static ECKey fromPrivate(BigInteger privKey, boolean compressed) {
|
public static ECKey fromPrivate(BigInteger privKey, boolean compressed) {
|
||||||
ECPoint point = publicPointFromPrivate(privKey);
|
ECPoint point = publicPointFromPrivate(privKey);
|
||||||
|
@ -267,8 +251,8 @@ public class ECKey implements EncryptableItem {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates an ECKey given the private key only. The public key is calculated from it (this is slow), either
|
* Creates an ECKey given the private key only. The public key is calculated from it (this is slow).
|
||||||
* compressed or not.
|
* @param compressed Determines whether the resulting ECKey will use a compressed encoding for the public key.
|
||||||
*/
|
*/
|
||||||
public static ECKey fromPrivate(byte[] privKeyBytes, boolean compressed) {
|
public static ECKey fromPrivate(byte[] privKeyBytes, boolean compressed) {
|
||||||
return fromPrivate(new BigInteger(1, privKeyBytes), compressed);
|
return fromPrivate(new BigInteger(1, privKeyBytes), compressed);
|
||||||
|
@ -277,10 +261,11 @@ public class ECKey implements EncryptableItem {
|
||||||
/**
|
/**
|
||||||
* Creates an ECKey that simply trusts the caller to ensure that point is really the result of multiplying the
|
* Creates an ECKey that simply trusts the caller to ensure that point is really the result of multiplying the
|
||||||
* generator point by the private key. This is used to speed things up when you know you have the right values
|
* generator point by the private key. This is used to speed things up when you know you have the right values
|
||||||
* already. The compression state of pub will be preserved.
|
* already.
|
||||||
|
* @param compressed Determines whether the resulting ECKey will use a compressed encoding for the public key.
|
||||||
*/
|
*/
|
||||||
public static ECKey fromPrivateAndPrecalculatedPublic(BigInteger priv, ECPoint pub) {
|
public static ECKey fromPrivateAndPrecalculatedPublic(BigInteger priv, ECPoint pub, boolean compressed) {
|
||||||
return new ECKey(priv, pub);
|
return new ECKey(priv, pub, compressed);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -291,15 +276,15 @@ public class ECKey implements EncryptableItem {
|
||||||
public static ECKey fromPrivateAndPrecalculatedPublic(byte[] priv, byte[] pub) {
|
public static ECKey fromPrivateAndPrecalculatedPublic(byte[] priv, byte[] pub) {
|
||||||
checkNotNull(priv);
|
checkNotNull(priv);
|
||||||
checkNotNull(pub);
|
checkNotNull(pub);
|
||||||
return new ECKey(new BigInteger(1, priv), CURVE.getCurve().decodePoint(pub));
|
return new ECKey(new BigInteger(1, priv), new LazyECPoint(CURVE.getCurve(), pub));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates an ECKey that cannot be used for signing, only verifying signatures, from the given point. The
|
* Creates an ECKey that cannot be used for signing, only verifying signatures, from the given point.
|
||||||
* compression state of pub will be preserved.
|
* @param compressed Determines whether the resulting ECKey will use a compressed encoding for the public key.
|
||||||
*/
|
*/
|
||||||
public static ECKey fromPublicOnly(ECPoint pub) {
|
public static ECKey fromPublicOnly(ECPoint pub, boolean compressed) {
|
||||||
return new ECKey(null, pub);
|
return new ECKey(null, pub, compressed);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -307,7 +292,11 @@ public class ECKey implements EncryptableItem {
|
||||||
* The compression state of pub will be preserved.
|
* The compression state of pub will be preserved.
|
||||||
*/
|
*/
|
||||||
public static ECKey fromPublicOnly(byte[] pub) {
|
public static ECKey fromPublicOnly(byte[] pub) {
|
||||||
return new ECKey(null, CURVE.getCurve().decodePoint(pub));
|
return new ECKey(null, new LazyECPoint(CURVE.getCurve(), pub));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ECKey fromPublicOnly(ECKey key) {
|
||||||
|
return fromPublicOnly(key.getPubKeyPoint(), key.isCompressed());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -318,7 +307,7 @@ public class ECKey implements EncryptableItem {
|
||||||
if (!pub.isCompressed())
|
if (!pub.isCompressed())
|
||||||
return this;
|
return this;
|
||||||
else
|
else
|
||||||
return new ECKey(priv, decompressPoint(pub.get()));
|
return new ECKey(priv, getPointWithCompression(pub.get(), false));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -373,8 +362,7 @@ public class ECKey implements EncryptableItem {
|
||||||
if (pubKey == null) {
|
if (pubKey == null) {
|
||||||
// Derive public from private.
|
// Derive public from private.
|
||||||
ECPoint point = publicPointFromPrivate(privKey);
|
ECPoint point = publicPointFromPrivate(privKey);
|
||||||
point = getPointWithCompression(point, compressed);
|
this.pub = getPointWithCompression(point, compressed);
|
||||||
this.pub = new LazyECPoint(point);
|
|
||||||
} else {
|
} else {
|
||||||
// We expect the pubkey to be in regular encoded form, just as a BigInteger. Therefore the first byte is
|
// We expect the pubkey to be in regular encoded form, just as a BigInteger. Therefore the first byte is
|
||||||
// a special marker byte.
|
// a special marker byte.
|
||||||
|
@ -853,7 +841,7 @@ public class ECKey implements EncryptableItem {
|
||||||
|
|
||||||
// Now sanity check to ensure the pubkey bytes match the privkey.
|
// Now sanity check to ensure the pubkey bytes match the privkey.
|
||||||
boolean compressed = isPubKeyCompressed(pubbits);
|
boolean compressed = isPubKeyCompressed(pubbits);
|
||||||
ECKey key = new ECKey(privkey, null, compressed);
|
ECKey key = new ECKey(privkey, (byte[]) null, compressed);
|
||||||
if (!Arrays.equals(key.getPubKey(), pubbits))
|
if (!Arrays.equals(key.getPubKey(), pubbits))
|
||||||
throw new IllegalArgumentException("Public key in ASN.1 structure does not match private key.");
|
throw new IllegalArgumentException("Public key in ASN.1 structure does not match private key.");
|
||||||
return key;
|
return key;
|
||||||
|
@ -1036,7 +1024,7 @@ public class ECKey implements EncryptableItem {
|
||||||
BigInteger srInv = rInv.multiply(sig.s).mod(n);
|
BigInteger srInv = rInv.multiply(sig.s).mod(n);
|
||||||
BigInteger eInvrInv = rInv.multiply(eInv).mod(n);
|
BigInteger eInvrInv = rInv.multiply(eInv).mod(n);
|
||||||
ECPoint q = ECAlgorithms.sumOfTwoMultiplies(CURVE.getG(), eInvrInv, R, srInv);
|
ECPoint q = ECAlgorithms.sumOfTwoMultiplies(CURVE.getG(), eInvrInv, R, srInv);
|
||||||
return ECKey.fromPublicOnly(q.getEncoded(compressed));
|
return ECKey.fromPublicOnly(q, 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). */
|
||||||
|
@ -1121,9 +1109,7 @@ public class ECKey implements EncryptableItem {
|
||||||
if (unencryptedPrivateKey.length != 32)
|
if (unencryptedPrivateKey.length != 32)
|
||||||
throw new KeyCrypterException.InvalidCipherText(
|
throw new KeyCrypterException.InvalidCipherText(
|
||||||
"Decrypted key must be 32 bytes long, but is " + unencryptedPrivateKey.length);
|
"Decrypted key must be 32 bytes long, but is " + unencryptedPrivateKey.length);
|
||||||
ECKey key = ECKey.fromPrivate(unencryptedPrivateKey);
|
ECKey key = ECKey.fromPrivate(unencryptedPrivateKey, isCompressed());
|
||||||
if (!isCompressed())
|
|
||||||
key = key.decompress();
|
|
||||||
if (!Arrays.equals(key.getPubKey(), getPubKey()))
|
if (!Arrays.equals(key.getPubKey(), getPubKey()))
|
||||||
throw new KeyCrypterException("Provided AES key is wrong");
|
throw new KeyCrypterException("Provided AES key is wrong");
|
||||||
key.setCreationTimeSeconds(creationTimeSeconds);
|
key.setCreationTimeSeconds(creationTimeSeconds);
|
||||||
|
|
|
@ -79,9 +79,10 @@ public class DeterministicKey extends ECKey {
|
||||||
public DeterministicKey(List<ChildNumber> childNumberPath,
|
public DeterministicKey(List<ChildNumber> childNumberPath,
|
||||||
byte[] chainCode,
|
byte[] chainCode,
|
||||||
ECPoint publicAsPoint,
|
ECPoint publicAsPoint,
|
||||||
|
boolean compressed,
|
||||||
@Nullable BigInteger priv,
|
@Nullable BigInteger priv,
|
||||||
@Nullable DeterministicKey parent) {
|
@Nullable DeterministicKey parent) {
|
||||||
this(childNumberPath, chainCode, new LazyECPoint(publicAsPoint), priv, parent);
|
this(childNumberPath, chainCode, new LazyECPoint(publicAsPoint, compressed), priv, parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Constructs a key from its components. This is not normally something you should use. */
|
/** Constructs a key from its components. This is not normally something you should use. */
|
||||||
|
@ -89,7 +90,7 @@ public class DeterministicKey extends ECKey {
|
||||||
byte[] chainCode,
|
byte[] chainCode,
|
||||||
BigInteger priv,
|
BigInteger priv,
|
||||||
@Nullable DeterministicKey parent) {
|
@Nullable DeterministicKey parent) {
|
||||||
super(priv, compressPoint(ECKey.publicPointFromPrivate(priv)));
|
super(priv, ECKey.publicPointFromPrivate(priv), true);
|
||||||
checkArgument(chainCode.length == 32);
|
checkArgument(chainCode.length == 32);
|
||||||
this.parent = parent;
|
this.parent = parent;
|
||||||
this.childNumberPath = HDPath.M(checkNotNull(childNumberPath));
|
this.childNumberPath = HDPath.M(checkNotNull(childNumberPath));
|
||||||
|
@ -157,7 +158,7 @@ public class DeterministicKey extends ECKey {
|
||||||
@Nullable DeterministicKey parent,
|
@Nullable DeterministicKey parent,
|
||||||
int depth,
|
int depth,
|
||||||
int parentFingerprint) {
|
int parentFingerprint) {
|
||||||
super(priv, compressPoint(ECKey.publicPointFromPrivate(priv)));
|
super(priv, ECKey.publicPointFromPrivate(priv), true);
|
||||||
checkArgument(chainCode.length == 32);
|
checkArgument(chainCode.length == 32);
|
||||||
this.parent = parent;
|
this.parent = parent;
|
||||||
this.childNumberPath = HDPath.M(checkNotNull(childNumberPath));
|
this.childNumberPath = HDPath.M(checkNotNull(childNumberPath));
|
||||||
|
@ -169,7 +170,7 @@ public class DeterministicKey extends ECKey {
|
||||||
|
|
||||||
/** Clones the key */
|
/** Clones the key */
|
||||||
public DeterministicKey(DeterministicKey keyToClone, DeterministicKey newParent) {
|
public DeterministicKey(DeterministicKey keyToClone, DeterministicKey newParent) {
|
||||||
super(keyToClone.priv, keyToClone.pub.get());
|
super(keyToClone.priv, keyToClone.pub.get(), keyToClone.pub.isCompressed());
|
||||||
this.parent = newParent;
|
this.parent = newParent;
|
||||||
this.childNumberPath = keyToClone.childNumberPath;
|
this.childNumberPath = keyToClone.childNumberPath;
|
||||||
this.chainCode = keyToClone.chainCode;
|
this.chainCode = keyToClone.chainCode;
|
||||||
|
|
|
@ -37,6 +37,7 @@ public class LazyECPoint {
|
||||||
|
|
||||||
private final ECCurve curve;
|
private final ECCurve curve;
|
||||||
private final byte[] bits;
|
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
|
// This field is effectively final - once set it won't change again. However it can be set after
|
||||||
// construction.
|
// construction.
|
||||||
|
@ -46,10 +47,12 @@ public class LazyECPoint {
|
||||||
public LazyECPoint(ECCurve curve, byte[] bits) {
|
public LazyECPoint(ECCurve curve, byte[] bits) {
|
||||||
this.curve = curve;
|
this.curve = curve;
|
||||||
this.bits = bits;
|
this.bits = bits;
|
||||||
|
this.compressed = ECKey.isPubKeyCompressed(bits);
|
||||||
}
|
}
|
||||||
|
|
||||||
public LazyECPoint(ECPoint point) {
|
public LazyECPoint(ECPoint point, boolean compressed) {
|
||||||
this.point = checkNotNull(point);
|
this.point = checkNotNull(point).normalize();
|
||||||
|
this.compressed = compressed;
|
||||||
this.curve = null;
|
this.curve = null;
|
||||||
this.bits = null;
|
this.bits = null;
|
||||||
}
|
}
|
||||||
|
@ -60,17 +63,17 @@ public class LazyECPoint {
|
||||||
return point;
|
return point;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delegated methods.
|
|
||||||
|
|
||||||
public ECPoint getDetachedPoint() {
|
|
||||||
return get().getDetachedPoint();
|
|
||||||
}
|
|
||||||
|
|
||||||
public byte[] getEncoded() {
|
public byte[] getEncoded() {
|
||||||
if (bits != null)
|
if (bits != null)
|
||||||
return Arrays.copyOf(bits, bits.length);
|
return Arrays.copyOf(bits, bits.length);
|
||||||
else
|
else
|
||||||
return get().getEncoded();
|
return get().getEncoded(compressed);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delegated methods.
|
||||||
|
|
||||||
|
public ECPoint getDetachedPoint() {
|
||||||
|
return get().getDetachedPoint();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isInfinity() {
|
public boolean isInfinity() {
|
||||||
|
@ -94,10 +97,7 @@ public class LazyECPoint {
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isCompressed() {
|
public boolean isCompressed() {
|
||||||
if (bits != null)
|
return compressed;
|
||||||
return ECKey.isPubKeyCompressed(bits);
|
|
||||||
else
|
|
||||||
return get().isCompressed();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public ECPoint multiply(BigInteger k) {
|
public ECPoint multiply(BigInteger k) {
|
||||||
|
|
|
@ -79,7 +79,7 @@ public class BloomFilterTest {
|
||||||
|
|
||||||
KeyChainGroup group = KeyChainGroup.builder(MAINNET).build();
|
KeyChainGroup group = KeyChainGroup.builder(MAINNET).build();
|
||||||
// Add a random key which happens to have been used in a recent generation
|
// Add a random key which happens to have been used in a recent generation
|
||||||
group.importKeys(ECKey.fromPublicOnly(privKey.getKey().getPubKeyPoint()), ECKey.fromPublicOnly(HEX.decode("03cb219f69f1b49468bd563239a86667e74a06fcba69ac50a08a5cbc42a5808e99")));
|
group.importKeys(ECKey.fromPublicOnly(privKey.getKey()), ECKey.fromPublicOnly(HEX.decode("03cb219f69f1b49468bd563239a86667e74a06fcba69ac50a08a5cbc42a5808e99")));
|
||||||
Wallet wallet = new Wallet(MAINNET, group);
|
Wallet wallet = new Wallet(MAINNET, group);
|
||||||
wallet.commitTx(new Transaction(MAINNET, HEX.decode("01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0d038754030114062f503253482fffffffff01c05e559500000000232103cb219f69f1b49468bd563239a86667e74a06fcba69ac50a08a5cbc42a5808e99ac00000000")));
|
wallet.commitTx(new Transaction(MAINNET, HEX.decode("01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0d038754030114062f503253482fffffffff01c05e559500000000232103cb219f69f1b49468bd563239a86667e74a06fcba69ac50a08a5cbc42a5808e99ac00000000")));
|
||||||
|
|
||||||
|
|
|
@ -152,7 +152,7 @@ public class ECKeyTest {
|
||||||
// Now re-encode and decode the ASN.1 to see if it is equivalent (it does not produce the exact same byte
|
// Now re-encode and decode the ASN.1 to see if it is equivalent (it does not produce the exact same byte
|
||||||
// sequence, some integers are padded now).
|
// sequence, some integers are padded now).
|
||||||
ECKey roundtripKey =
|
ECKey roundtripKey =
|
||||||
ECKey.fromPrivateAndPrecalculatedPublic(decodedKey.getPrivKey(), decodedKey.getPubKeyPoint());
|
ECKey.fromPrivateAndPrecalculatedPublic(decodedKey.getPrivKey(), decodedKey.getPubKeyPoint(), decodedKey.isCompressed());
|
||||||
|
|
||||||
for (ECKey key : new ECKey[] {decodedKey, roundtripKey}) {
|
for (ECKey key : new ECKey[] {decodedKey, roundtripKey}) {
|
||||||
byte[] message = reverseBytes(HEX.decode(
|
byte[] message = reverseBytes(HEX.decode(
|
||||||
|
@ -239,7 +239,7 @@ public class ECKeyTest {
|
||||||
String message = "Hello World!";
|
String message = "Hello World!";
|
||||||
Sha256Hash hash = Sha256Hash.of(message.getBytes());
|
Sha256Hash hash = Sha256Hash.of(message.getBytes());
|
||||||
ECKey.ECDSASignature sig = key.sign(hash);
|
ECKey.ECDSASignature sig = key.sign(hash);
|
||||||
key = ECKey.fromPublicOnly(key.getPubKeyPoint());
|
key = ECKey.fromPublicOnly(key);
|
||||||
|
|
||||||
List<Byte> possibleRecIds = Lists.newArrayList((byte) 0, (byte) 1, (byte) 2, (byte) 3);
|
List<Byte> possibleRecIds = Lists.newArrayList((byte) 0, (byte) 1, (byte) 2, (byte) 3);
|
||||||
byte recId = key.findRecoveryId(hash, sig);
|
byte recId = key.findRecoveryId(hash, sig);
|
||||||
|
@ -255,13 +255,13 @@ public class ECKeyTest {
|
||||||
String message = "Maarten Bodewes generated this test vector on 2016-11-08";
|
String message = "Maarten Bodewes generated this test vector on 2016-11-08";
|
||||||
Sha256Hash hash = Sha256Hash.of(message.getBytes());
|
Sha256Hash hash = Sha256Hash.of(message.getBytes());
|
||||||
ECKey.ECDSASignature sig = key.sign(hash);
|
ECKey.ECDSASignature sig = key.sign(hash);
|
||||||
key = ECKey.fromPublicOnly(key.getPubKeyPoint());
|
key = ECKey.fromPublicOnly(key);
|
||||||
|
|
||||||
byte recId = key.findRecoveryId(hash, sig);
|
byte recId = key.findRecoveryId(hash, sig);
|
||||||
byte expectedRecId = 0;
|
byte expectedRecId = 0;
|
||||||
assertEquals(recId, expectedRecId);
|
assertEquals(recId, expectedRecId);
|
||||||
|
|
||||||
ECKey pubKey = ECKey.fromPublicOnly(key.getPubKeyPoint());
|
ECKey pubKey = ECKey.fromPublicOnly(key);
|
||||||
ECKey recoveredKey = ECKey.recoverFromSignature(recId, sig, hash, true);
|
ECKey recoveredKey = ECKey.recoverFromSignature(recId, sig, hash, true);
|
||||||
assertEquals(recoveredKey, pubKey);
|
assertEquals(recoveredKey, pubKey);
|
||||||
}
|
}
|
||||||
|
@ -274,7 +274,7 @@ public class ECKeyTest {
|
||||||
ECKey.ECDSASignature sig = key.sign(hash);
|
ECKey.ECDSASignature sig = key.sign(hash);
|
||||||
|
|
||||||
byte recId = key.findRecoveryId(hash, sig);
|
byte recId = key.findRecoveryId(hash, sig);
|
||||||
ECKey pubKey = ECKey.fromPublicOnly(key.getPubKeyPoint());
|
ECKey pubKey = ECKey.fromPublicOnly(key);
|
||||||
ECKey recoveredKey = ECKey.recoverFromSignature(recId, sig, hash, true);
|
ECKey recoveredKey = ECKey.recoverFromSignature(recId, sig, hash, true);
|
||||||
assertEquals(recoveredKey, pubKey);
|
assertEquals(recoveredKey, pubKey);
|
||||||
}
|
}
|
||||||
|
@ -285,7 +285,7 @@ public class ECKeyTest {
|
||||||
String message = "Hello World!";
|
String message = "Hello World!";
|
||||||
Sha256Hash hash = Sha256Hash.of(message.getBytes());
|
Sha256Hash hash = Sha256Hash.of(message.getBytes());
|
||||||
ECKey.ECDSASignature sig = key.sign(hash);
|
ECKey.ECDSASignature sig = key.sign(hash);
|
||||||
key = ECKey.fromPublicOnly(key.getPubKeyPoint());
|
key = ECKey.fromPublicOnly(key);
|
||||||
boolean found = false;
|
boolean found = false;
|
||||||
for (int i = 0; i < 4; i++) {
|
for (int i = 0; i < 4; i++) {
|
||||||
ECKey key2 = ECKey.recoverFromSignature(i, sig, hash, true);
|
ECKey key2 = ECKey.recoverFromSignature(i, sig, hash, true);
|
||||||
|
@ -384,7 +384,7 @@ public class ECKeyTest {
|
||||||
String message = "Goodbye Jupiter!";
|
String message = "Goodbye Jupiter!";
|
||||||
Sha256Hash hash = Sha256Hash.of(message.getBytes());
|
Sha256Hash hash = Sha256Hash.of(message.getBytes());
|
||||||
ECKey.ECDSASignature sig = encryptedKey.sign(hash, aesKey);
|
ECKey.ECDSASignature sig = encryptedKey.sign(hash, aesKey);
|
||||||
unencryptedKey = ECKey.fromPublicOnly(unencryptedKey.getPubKeyPoint());
|
unencryptedKey = ECKey.fromPublicOnly(unencryptedKey);
|
||||||
boolean found = false;
|
boolean found = false;
|
||||||
for (int i = 0; i < 4; i++) {
|
for (int i = 0; i < 4; i++) {
|
||||||
ECKey key2 = ECKey.recoverFromSignature(i, sig, hash, true);
|
ECKey key2 = ECKey.recoverFromSignature(i, sig, hash, true);
|
||||||
|
@ -520,7 +520,7 @@ public class ECKeyTest {
|
||||||
@Test
|
@Test
|
||||||
public void testPublicKeysAreEqual() {
|
public void testPublicKeysAreEqual() {
|
||||||
ECKey key = new ECKey();
|
ECKey key = new ECKey();
|
||||||
ECKey pubKey1 = ECKey.fromPublicOnly(key.getPubKeyPoint());
|
ECKey pubKey1 = ECKey.fromPublicOnly(key);
|
||||||
assertTrue(pubKey1.isCompressed());
|
assertTrue(pubKey1.isCompressed());
|
||||||
ECKey pubKey2 = pubKey1.decompress();
|
ECKey pubKey2 = pubKey1.decompress();
|
||||||
assertEquals(pubKey1, pubKey2);
|
assertEquals(pubKey1, pubKey2);
|
||||||
|
|
|
@ -91,7 +91,7 @@ public class ScriptTest {
|
||||||
Script script = ScriptBuilder.createMultiSigOutputScript(3, keys);
|
Script script = ScriptBuilder.createMultiSigOutputScript(3, keys);
|
||||||
assertTrue(ScriptPattern.isSentToMultisig(script));
|
assertTrue(ScriptPattern.isSentToMultisig(script));
|
||||||
List<ECKey> pubkeys = new ArrayList<>(3);
|
List<ECKey> pubkeys = new ArrayList<>(3);
|
||||||
for (ECKey key : keys) pubkeys.add(ECKey.fromPublicOnly(key.getPubKeyPoint()));
|
for (ECKey key : keys) pubkeys.add(ECKey.fromPublicOnly(key));
|
||||||
assertEquals(script.getPubKeys(), pubkeys);
|
assertEquals(script.getPubKeys(), pubkeys);
|
||||||
assertFalse(ScriptPattern.isSentToMultisig(ScriptBuilder.createP2PKOutputScript(new ECKey())));
|
assertFalse(ScriptPattern.isSentToMultisig(ScriptBuilder.createP2PKOutputScript(new ECKey())));
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -233,7 +233,7 @@ public class BasicKeyChainTest {
|
||||||
@Test
|
@Test
|
||||||
public void watching() throws UnreadableWalletException {
|
public void watching() throws UnreadableWalletException {
|
||||||
ECKey key1 = new ECKey();
|
ECKey key1 = new ECKey();
|
||||||
ECKey pub = ECKey.fromPublicOnly(key1.getPubKeyPoint());
|
ECKey pub = ECKey.fromPublicOnly(key1);
|
||||||
chain.importKeys(pub);
|
chain.importKeys(pub);
|
||||||
assertEquals(1, chain.numKeys());
|
assertEquals(1, chain.numKeys());
|
||||||
List<Protos.Key> keys = chain.serializeToProtobuf();
|
List<Protos.Key> keys = chain.serializeToProtobuf();
|
||||||
|
|
|
@ -649,7 +649,7 @@ public class KeyChainGroupTest {
|
||||||
"xpub69bjfJ91ikC5ghsqsVDHNq2dRGaV2HHVx7Y9LXi27LN9BWWAXPTQr4u8U3wAtap8bLdHdkqPpAcZmhMS5SnrMQC4ccaoBccFhh315P4UYzo",
|
"xpub69bjfJ91ikC5ghsqsVDHNq2dRGaV2HHVx7Y9LXi27LN9BWWAXPTQr4u8U3wAtap8bLdHdkqPpAcZmhMS5SnrMQC4ccaoBccFhh315P4UYzo",
|
||||||
MAINNET)).outputScriptType(Script.ScriptType.P2PKH).build())
|
MAINNET)).outputScriptType(Script.ScriptType.P2PKH).build())
|
||||||
.build();
|
.build();
|
||||||
final ECKey watchingKey = ECKey.fromPublicOnly(new ECKey().getPubKeyPoint());
|
final ECKey watchingKey = ECKey.fromPublicOnly(new ECKey());
|
||||||
group.importKeys(watchingKey);
|
group.importKeys(watchingKey);
|
||||||
assertTrue(group.isWatching());
|
assertTrue(group.isWatching());
|
||||||
}
|
}
|
||||||
|
|
|
@ -3197,7 +3197,7 @@ public class WalletTest extends TestWithWallet {
|
||||||
public void completeTxPartiallySigned(Wallet.MissingSigsMode missSigMode, byte[] expectedSig) throws Exception {
|
public void completeTxPartiallySigned(Wallet.MissingSigsMode missSigMode, byte[] expectedSig) throws Exception {
|
||||||
// Check the wallet will write dummy scriptSigs for inputs that we have only pubkeys for without the privkey.
|
// Check the wallet will write dummy scriptSigs for inputs that we have only pubkeys for without the privkey.
|
||||||
ECKey priv = new ECKey();
|
ECKey priv = new ECKey();
|
||||||
ECKey pub = ECKey.fromPublicOnly(priv.getPubKeyPoint());
|
ECKey pub = ECKey.fromPublicOnly(priv);
|
||||||
wallet.importKey(pub);
|
wallet.importKey(pub);
|
||||||
ECKey priv2 = wallet.freshReceiveKey();
|
ECKey priv2 = wallet.freshReceiveKey();
|
||||||
// Send three transactions, with one being an address type and the other being a raw CHECKSIG type pubkey only,
|
// Send three transactions, with one being an address type and the other being a raw CHECKSIG type pubkey only,
|
||||||
|
|
Loading…
Add table
Reference in a new issue