/** * A deterministic key is considered to be 'public key only' if it hasn't got a private key part and it cannot be * rederived. If the hierarchy is encrypted this returns true. */ @Override public boolean isPubKeyOnly() { return super.isPubKeyOnly() && (parent == null || parent.isPubKeyOnly()); }
/** * A deterministic key is considered to be 'public key only' if it hasn't got a private key part and it cannot be * rederived. If the hierarchy is encrypted this returns true. */ @Override public boolean isPubKeyOnly() { return super.isPubKeyOnly() && (parent == null || parent.isPubKeyOnly()); }
/** * A deterministic key is considered to be 'public key only' if it hasn't got a private key part and it cannot be * rederived. If the hierarchy is encrypted this returns true. */ @Override public boolean isPubKeyOnly() { return super.isPubKeyOnly() && (parent == null || parent.isPubKeyOnly()); }
/** * A deterministic key is considered to be 'public key only' if it hasn't got a private key part and it cannot be * rederived. If the hierarchy is encrypted this returns true. */ @Override public boolean isPubKeyOnly() { return super.isPubKeyOnly() && (parent == null || parent.isPubKeyOnly()); }
@Override public String toString() { final MoreObjects.ToStringHelper helper = MoreObjects.toStringHelper(this).omitNullValues(); helper.add("pub", Utils.HEX.encode(pub.getEncoded())); helper.add("chainCode", HEX.encode(chainCode)); helper.add("path", getPathAsString()); if (creationTimeSeconds > 0) helper.add("creationTimeSeconds", creationTimeSeconds); helper.add("isEncrypted", isEncrypted()); helper.add("isPubKeyOnly", isPubKeyOnly()); return helper.toString(); }
@Override public String toString() { final MoreObjects.ToStringHelper helper = MoreObjects.toStringHelper(this).omitNullValues(); helper.add("pub", Utils.HEX.encode(pub.getEncoded())); helper.add("chainCode", HEX.encode(chainCode)); helper.add("path", getPathAsString()); if (creationTimeSeconds > 0) helper.add("creationTimeSeconds", creationTimeSeconds); helper.add("isEncrypted", isEncrypted()); helper.add("isPubKeyOnly", isPubKeyOnly()); return helper.toString(); }
@Override public String toString() { final MoreObjects.ToStringHelper helper = MoreObjects.toStringHelper(this).omitNullValues(); helper.add("pub", Utils.HEX.encode(pub.getEncoded())); helper.add("chainCode", HEX.encode(chainCode)); helper.add("path", getPathAsString()); if (creationTimeSeconds > 0) helper.add("creationTimeSeconds", creationTimeSeconds); helper.add("isEncrypted", isEncrypted()); helper.add("isPubKeyOnly", isPubKeyOnly()); return helper.toString(); }
@Override public String toString() { final MoreObjects.ToStringHelper helper = MoreObjects.toStringHelper(this).omitNullValues(); helper.add("pub", Utils.HEX.encode(pub.getEncoded())); helper.add("chainCode", HEX.encode(chainCode)); helper.add("path", getPathAsString()); if (creationTimeSeconds > 0) helper.add("creationTimeSeconds", creationTimeSeconds); helper.add("isEncrypted", isEncrypted()); helper.add("isPubKeyOnly", isPubKeyOnly()); return helper.toString(); }
@Override public SimpleHDKeyChain toEncrypted(CharSequence password) { checkNotNull(password, "Attempt to encrypt with a null password."); checkArgument(password.length() > 0, "Attempt to encrypt with an empty password."); checkState(!rootKey.isEncrypted(), "Attempt to encrypt a root key that is already encrypted."); checkState(!rootKey.isPubKeyOnly(), "Attempt to encrypt a watching chain."); KeyCrypter scrypt = new KeyCrypterScrypt(); KeyParameter derivedKey = scrypt.deriveKey(password); return toEncrypted(scrypt, derivedKey); }
@Override public SimpleHDKeyChain toEncrypted(CharSequence password) { checkNotNull(password, "Attempt to encrypt with a null password."); checkArgument(password.length() > 0, "Attempt to encrypt with an empty password."); checkState(!rootKey.isEncrypted(), "Attempt to encrypt a root key that is already encrypted."); checkState(!rootKey.isPubKeyOnly(), "Attempt to encrypt a watching chain."); KeyCrypter scrypt = new KeyCrypterScrypt(); KeyParameter derivedKey = scrypt.deriveKey(password); return toEncrypted(scrypt, derivedKey); }
/** * Creates a deterministic key chain that watches the given (public only) root key. You can use this to calculate * balances and generally follow along, but spending is not possible with such a chain. Currently you can't use * this method to watch an arbitrary fragment of some other tree, this limitation may be removed in future. */ public DeterministicKeyChain(DeterministicKey watchingKey) { checkArgument(watchingKey.isPubKeyOnly(), "Private subtrees not currently supported: if you got this key from DKC.getWatchingKey() then use .dropPrivate().dropParent() on it first."); checkArgument(watchingKey.getPath().size() == getAccountPath().size(), "You can only watch an account key currently"); basicKeyChain = new BasicKeyChain(); this.seed = null; this.rootKey = null; basicKeyChain.importKey(watchingKey); hierarchy = new DeterministicHierarchy(watchingKey); initializeHierarchyUnencrypted(watchingKey); }
/** * Returns the same key with the private bytes removed. May return the same instance. The purpose of this is to save * memory: the private key can always be very efficiently rederived from a parent that a private key, so storing * all the private keys in RAM is a poor tradeoff especially on constrained devices. This means that the returned * key may still be usable for signing and so on, so don't expect it to be a true pubkey-only object! If you want * that then you should follow this call with a call to {@link #dropParent()}. */ public DeterministicKey dropPrivateBytes() { if (isPubKeyOnly()) return this; else return new DeterministicKey(getPath(), getChainCode(), pub, null, parent); }
/** * Creates a deterministic key chain that watches the given (public only) root key. You can use this to calculate * balances and generally follow along, but spending is not possible with such a chain. Currently you can't use * this method to watch an arbitrary fragment of some other tree, this limitation may be removed in future. */ public DeterministicKeyChain(DeterministicKey watchingKey) { checkArgument(watchingKey.isPubKeyOnly(), "Private subtrees not currently supported: if you got this key from DKC.getWatchingKey() then use .dropPrivate().dropParent() on it first."); checkArgument(watchingKey.getPath().size() == getAccountPath().size(), "You can only watch an account key currently"); basicKeyChain = new BasicKeyChain(); this.seed = null; rootKey = null; addToBasicChain(watchingKey); hierarchy = new DeterministicHierarchy(watchingKey); initializeHierarchyUnencrypted(watchingKey); }
/** * Returns the same key with the private bytes removed. May return the same instance. The purpose of this is to save * memory: the private key can always be very efficiently rederived from a parent that a private key, so storing * all the private keys in RAM is a poor tradeoff especially on constrained devices. This means that the returned * key may still be usable for signing and so on, so don't expect it to be a true pubkey-only object! If you want * that then you should follow this call with a call to {@link #dropParent()}. */ public DeterministicKey dropPrivateBytes() { if (isPubKeyOnly()) return this; else return new DeterministicKey(getPath(), getChainCode(), pub, null, parent); }
/** * Returns the same key with the private bytes removed. May return the same instance. The purpose of this is to save * memory: the private key can always be very efficiently rederived from a parent that a private key, so storing * all the private keys in RAM is a poor tradeoff especially on constrained devices. This means that the returned * key may still be usable for signing and so on, so don't expect it to be a true pubkey-only object! If you want * that then you should follow this call with a call to {@link #dropParent()}. */ public DeterministicKey dropPrivateBytes() { if (isPubKeyOnly()) return this; else return new DeterministicKey(getPath(), getChainCode(), pub, null, parent); }
/** * Creates a deterministic key chain that watches the given (public only) root key. You can use this to calculate * balances and generally follow along, but spending is not possible with such a chain. Currently you can't use * this method to watch an arbitrary fragment of some other tree, this limitation may be removed in future. */ public DeterministicKeyChain(DeterministicKey watchingKey, boolean useSegwit) { checkArgument(watchingKey.isPubKeyOnly(), "Private subtrees not currently supported: if you got this key from DKC.getWatchingKey() then use .dropPrivate().dropParent() on it first."); checkArgument(watchingKey.getPath().size() == getAccountPath().size(), "You can only watch an account key currently"); this.useSegwit = useSegwit; basicKeyChain = new BasicKeyChain(useSegwit); this.seed = null; this.rootKey = null; basicKeyChain.importKey(watchingKey); hierarchy = new DeterministicHierarchy(watchingKey); initializeHierarchyUnencrypted(watchingKey); }
/** * Returns the same key with the private bytes removed. May return the same instance. The purpose of this is to save * memory: the private key can always be very efficiently rederived from a parent that a private key, so storing * all the private keys in RAM is a poor tradeoff especially on constrained devices. This means that the returned * key may still be usable for signing and so on, so don't expect it to be a true pubkey-only object! If you want * that then you should follow this call with a call to {@link #dropParent()}. */ public DeterministicKey dropPrivateBytes() { if (isPubKeyOnly()) return this; else return new DeterministicKey(getPath(), getChainCode(), pub, null, parent); }
/** * Creates a deterministic key chain that watches the given (public only) root key. You can use this to calculate * balances and generally follow along, but spending is not possible with such a chain. */ public DeterministicKeyChain(DeterministicKey watchingKey) { checkArgument(watchingKey.isPubKeyOnly(), "Private subtrees not currently supported: if you got this key from DKC.getWatchingKey() then use .dropPrivate().dropParent() on it first."); setAccountPath(watchingKey.getPath()); basicKeyChain = new BasicKeyChain(); this.seed = null; rootKey = null; addToBasicChain(watchingKey); hierarchy = new DeterministicHierarchy(watchingKey); initializeHierarchyUnencrypted(watchingKey); }
@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); assertFalse(key3.isPubKeyOnly()); key2 = key2.dropPrivateBytes(); assertFalse(key2.isPubKeyOnly()); // still got private key bytes from the parents! // pubkey2 got its cached private key bytes (if any) dropped, and now it'll lose its parent too, so now it // becomes a true pubkey-only object. DeterministicKey pubkey2 = key2.dropParent(); DeterministicKey pubkey3 = HDKeyDerivation.deriveChildKey(pubkey2, ChildNumber.ZERO); assertTrue(pubkey3.isPubKeyOnly()); assertEquals(key3.getPubKeyPoint(), pubkey3.getPubKeyPoint()); }