public void encryption(SimpleHDKeyChain unencChain) throws UnreadableWalletException {
    DeterministicKey key1 = unencChain.getKey(KeyChain.KeyPurpose.RECEIVE_FUNDS);
    SimpleHDKeyChain encChain = unencChain.toEncrypted("open secret");
    DeterministicKey encKey1 = encChain.findKeyFromPubKey(key1.getPubKey());
    checkEncryptedKeyChain(encChain, key1);

    // Round-trip to ensure de/serialization works and that we can store two chains and they both
    // deserialize.
    List<Protos.Key> serialized = encChain.toProtobuf();
    System.out.println(protoToString(serialized));
    encChain = SimpleHDKeyChain.fromProtobuf(serialized, encChain.getKeyCrypter());
    checkEncryptedKeyChain(encChain, unencChain.findKeyFromPubKey(key1.getPubKey()));

    DeterministicKey encKey2 = encChain.getKey(KeyChain.KeyPurpose.RECEIVE_FUNDS);
    // Decrypt and check the keys match.
    SimpleHDKeyChain decChain = encChain.toDecrypted("open secret");
    DeterministicKey decKey1 = decChain.findKeyFromPubHash(encKey1.getPubKeyHash());
    DeterministicKey decKey2 = decChain.findKeyFromPubHash(encKey2.getPubKeyHash());
    assertEquals(decKey1.getPubKeyPoint(), encKey1.getPubKeyPoint());
    assertEquals(decKey2.getPubKeyPoint(), encKey2.getPubKeyPoint());
    assertFalse(decKey1.isEncrypted());
    assertFalse(decKey2.isEncrypted());
    assertNotEquals(encKey1.getParent(), decKey1.getParent()); // parts of a different hierarchy
    // Check we can once again derive keys from the decrypted chain.
    decChain.getKey(KeyChain.KeyPurpose.RECEIVE_FUNDS).sign(Sha256Hash.ZERO_HASH);
    decChain.getKey(KeyChain.KeyPurpose.CHANGE).sign(Sha256Hash.ZERO_HASH);
  }
  @Test
  public void deriveCoin() throws Exception {
    DeterministicHierarchy hierarchy = new DeterministicHierarchy(masterKey);
    DeterministicKey rootKey = hierarchy.get(BitcoinMain.get().getBip44Path(0), false, true);
    chain = new SimpleHDKeyChain(rootKey);

    ECKey key1 = chain.getKey(SimpleHDKeyChain.KeyPurpose.RECEIVE_FUNDS);
    ECKey key2 = chain.getKey(SimpleHDKeyChain.KeyPurpose.RECEIVE_FUNDS);

    final Address address = new Address(BitcoinMain.get(), "1Fp7CA7ZVqZNFVNQ9TpeqWUas7K28K9zig");
    assertEquals(address, key1.toAddress(BitcoinMain.get()));
    assertEquals(
        "1AKqkQM4VqyVis6hscj8695WHPCCzgHNY3", key2.toAddress(BitcoinMain.get()).toString());
    assertEquals(key1, chain.findKeyFromPubHash(address.getHash160()));
    assertEquals(key2, chain.findKeyFromPubKey(key2.getPubKey()));

    key1.sign(Sha256Hash.ZERO_HASH);

    ECKey key3 = chain.getKey(SimpleHDKeyChain.KeyPurpose.CHANGE);
    assertEquals(
        "18YvGiRqXKxrzB72ckfrRSizWeHgwRP94V", key3.toAddress(BitcoinMain.get()).toString());
    key3.sign(Sha256Hash.ZERO_HASH);

    ECKey key4 = chain.getKey(SimpleHDKeyChain.KeyPurpose.CHANGE);
    assertEquals(
        "1861TX2MbyPEUrxDQVWgV4Tp9991bK1zpy", key4.toAddress(BitcoinMain.get()).toString());
    key4.sign(Sha256Hash.ZERO_HASH);
  }
 private void checkEncryptedKeyChain(SimpleHDKeyChain encChain, DeterministicKey key1) {
   // Check we can look keys up and extend the chain without the AES key being provided.
   DeterministicKey encKey1 = encChain.findKeyFromPubKey(key1.getPubKey());
   DeterministicKey encKey2 = encChain.getKey(KeyChain.KeyPurpose.RECEIVE_FUNDS);
   assertFalse(key1.isEncrypted());
   assertTrue(encKey1.isEncrypted());
   assertEquals(encKey1.getPubKeyPoint(), key1.getPubKeyPoint());
   final KeyParameter aesKey = checkNotNull(encChain.getKeyCrypter()).deriveKey("open secret");
   encKey1.sign(Sha256Hash.ZERO_HASH, aesKey);
   encKey2.sign(Sha256Hash.ZERO_HASH, aesKey);
   assertTrue(encChain.checkAESKey(aesKey));
   assertFalse(encChain.checkPassword("access denied"));
   assertTrue(encChain.checkPassword("open secret"));
 }
  @Test
  public void derive() throws Exception {
    ECKey key1 = chain.getKey(SimpleHDKeyChain.KeyPurpose.RECEIVE_FUNDS);
    ECKey key2 = chain.getKey(SimpleHDKeyChain.KeyPurpose.RECEIVE_FUNDS);

    final Address address = new Address(UnitTestParams.get(), "n1bQNoEx8uhmCzzA5JPG6sFdtsUQhwiQJV");
    assertEquals(address, key1.toAddress(UnitTestParams.get()));
    assertEquals(
        "mnHUcqUVvrfi5kAaXJDQzBb9HsWs78b42R", key2.toAddress(UnitTestParams.get()).toString());
    assertEquals(key1, chain.findKeyFromPubHash(address.getHash160()));
    assertEquals(key2, chain.findKeyFromPubKey(key2.getPubKey()));

    key1.sign(Sha256Hash.ZERO_HASH);

    ECKey key3 = chain.getKey(SimpleHDKeyChain.KeyPurpose.CHANGE);
    assertEquals(
        "mqumHgVDqNzuXNrszBmi7A2UpmwaPMx4HQ", key3.toAddress(UnitTestParams.get()).toString());
    key3.sign(Sha256Hash.ZERO_HASH);
  }