3
0
mirror of https://github.com/Qortal/altcoinj.git synced 2025-02-13 10:45:51 +00:00

Implement DeterministicKey.isPubKeyOnly(). The super-implementation in ECKey doesn't take possible rederivation into account.

This commit is contained in:
Andreas Schildbach 2015-03-10 00:30:30 +01:00 committed by Mike Hearn
parent e9bffdda18
commit a1612b0a8f
5 changed files with 29 additions and 2 deletions

View File

@ -276,6 +276,20 @@ public class DeterministicKey extends ECKey {
return key;
}
/**
* A deterministic key is considered to be 'public key only' if it hasn't got a private key part and it cannot be
* rederived.
*/
@Override
public boolean isPubKeyOnly() {
if (!super.isPubKeyOnly())
return false;
if (parent != null)
return parent.isPubKeyOnly();
else
return true;
}
/**
* A deterministic key is considered to be encrypted if it has access to encrypted private key bytes, OR if its
* parent does. The reason is because the parent would be encrypted under the same key and this key knows how to

View File

@ -133,7 +133,7 @@ public final class HDKeyDerivation {
* if the resulting derived key is invalid (eg. private key == 0).
*/
public static DeterministicKey deriveChildKey(DeterministicKey parent, ChildNumber childNumber) throws HDDerivationException {
if (parent.isPubKeyOnly()) {
if (!parent.hasPrivKey()) {
RawKeyBytes rawKey = deriveChildKeyBytesFromPublic(parent, childNumber, PublicDeriveMode.NORMAL);
return new DeterministicKey(
HDUtils.append(parent.getPath(), childNumber),

View File

@ -171,9 +171,15 @@ public class ChildKeyDerivationTest {
@Test
public void pubOnlyDerivation() throws Exception {
DeterministicKey key1 = HDKeyDerivation.createMasterPrivateKey("satoshi lives!".getBytes());
assertFalse(key1.isPubKeyOnly());
DeterministicKey key2 = HDKeyDerivation.deriveChildKey(key1, ChildNumber.ZERO_HARDENED);
assertFalse(key2.isPubKeyOnly());
DeterministicKey key3 = HDKeyDerivation.deriveChildKey(key2, ChildNumber.ZERO);
DeterministicKey pubkey3 = HDKeyDerivation.deriveChildKey(key2.getPubOnly(), ChildNumber.ZERO);
assertFalse(key3.isPubKeyOnly());
DeterministicKey pubkey2 = key2.getPubOnly();
assertTrue(pubkey2.isPubKeyOnly());
DeterministicKey pubkey3 = HDKeyDerivation.deriveChildKey(pubkey2, ChildNumber.ZERO);
assertTrue(pubkey3.isPubKeyOnly());
assertEquals(key3.getPubKeyPoint(), pubkey3.getPubKeyPoint());
}

View File

@ -147,6 +147,7 @@ public class BasicKeyChainTest {
assertFalse(chain.checkPassword("wrong"));
ECKey key = chain.findKeyFromPubKey(key1.getPubKey());
assertTrue(key.isEncrypted());
assertTrue(key.isPubKeyOnly());
assertNull(key.getSecretBytes());
try {
@ -163,6 +164,7 @@ public class BasicKeyChainTest {
chain = chain.toDecrypted(PASSWORD);
key = chain.findKeyFromPubKey(key1.getPubKey());
assertFalse(key.isEncrypted());
assertFalse(key.isPubKeyOnly());
key.getPrivKeyBytes();
}

View File

@ -54,7 +54,9 @@ public class DeterministicKeyChainTest {
@Test
public void derive() throws Exception {
ECKey key1 = chain.getKey(KeyChain.KeyPurpose.RECEIVE_FUNDS);
assertFalse(key1.isPubKeyOnly());
ECKey key2 = chain.getKey(KeyChain.KeyPurpose.RECEIVE_FUNDS);
assertFalse(key2.isPubKeyOnly());
final Address address = new Address(UnitTestParams.get(), "n1bQNoEx8uhmCzzA5JPG6sFdtsUQhwiQJV");
assertEquals(address, key1.toAddress(UnitTestParams.get()));
@ -63,10 +65,13 @@ public class DeterministicKeyChainTest {
assertEquals(key2, chain.findKeyFromPubKey(key2.getPubKey()));
key1.sign(Sha256Hash.ZERO_HASH);
assertFalse(key1.isPubKeyOnly());
ECKey key3 = chain.getKey(KeyChain.KeyPurpose.CHANGE);
assertFalse(key3.isPubKeyOnly());
assertEquals("mqumHgVDqNzuXNrszBmi7A2UpmwaPMx4HQ", key3.toAddress(UnitTestParams.get()).toString());
key3.sign(Sha256Hash.ZERO_HASH);
assertFalse(key3.isPubKeyOnly());
}
@Test