Java Code Examples for org.bitcoinj.core.ECKey#setCreationTimeSeconds()

The following examples show how to use org.bitcoinj.core.ECKey#setCreationTimeSeconds() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: KeyChainGroupTest.java    From bcm-android with GNU General Public License v3.0 6 votes vote down vote up
@Test
public void earliestKeyTime() throws Exception {
    long now = Utils.currentTimeSeconds();   // mock
    long yesterday = now - 86400;
    assertEquals(now, group.getEarliestKeyCreationTime());
    Utils.rollMockClock(10000);
    group.freshKey(KeyChain.KeyPurpose.RECEIVE_FUNDS);
    Utils.rollMockClock(10000);
    group.freshKey(KeyChain.KeyPurpose.RECEIVE_FUNDS);
    // Check that all keys are assumed to be created at the same instant the seed is.
    assertEquals(now, group.getEarliestKeyCreationTime());
    ECKey key = new ECKey();
    key.setCreationTimeSeconds(yesterday);
    group.importKeys(key);
    assertEquals(yesterday, group.getEarliestKeyCreationTime());
}
 
Example 2
Source File: BasicKeyChain.java    From bcm-android with GNU General Public License v3.0 5 votes vote down vote up
private void deserializeFromProtobuf(List<Protos.Key> keys) throws UnreadableWalletException {
    lock.lock();
    try {
        checkState(hashToKeys.isEmpty(), "Tried to deserialize into a non-empty chain");
        for (Protos.Key key : keys) {
            if (key.getType() != Protos.Key.Type.ORIGINAL && key.getType() != Protos.Key.Type.ENCRYPTED_SCRYPT_AES)
                continue;
            boolean encrypted = key.getType() == Protos.Key.Type.ENCRYPTED_SCRYPT_AES;
            byte[] priv = key.hasSecretBytes() ? key.getSecretBytes().toByteArray() : null;
            if (!key.hasPublicKey())
                throw new UnreadableWalletException("Public key missing");
            byte[] pub = key.getPublicKey().toByteArray();
            ECKey ecKey;
            if (encrypted) {
                checkState(keyCrypter != null, "This wallet is encrypted but encrypt() was not called prior to deserialization");
                if (!key.hasEncryptedData())
                    throw new UnreadableWalletException("Encrypted private key data missing");
                Protos.EncryptedData proto = key.getEncryptedData();
                EncryptedData e = new EncryptedData(proto.getInitialisationVector().toByteArray(),
                        proto.getEncryptedPrivateKey().toByteArray());
                ecKey = ECKey.fromEncrypted(e, keyCrypter, pub);
            } else {
                if (priv != null)
                    ecKey = ECKey.fromPrivateAndPrecalculatedPublic(priv, pub);
                else
                    ecKey = ECKey.fromPublicOnly(pub);
            }
            ecKey.setCreationTimeSeconds(key.getCreationTimestamp() / 1000);
            importKeyLocked(ecKey);
        }
    } finally {
        lock.unlock();
    }
}
 
Example 3
Source File: BasicKeyChain.java    From green_android with GNU General Public License v3.0 5 votes vote down vote up
private void deserializeFromProtobuf(List<Protos.Key> keys) throws UnreadableWalletException {
    lock.lock();
    try {
        checkState(hashToKeys.isEmpty(), "Tried to deserialize into a non-empty chain");
        for (Protos.Key key : keys) {
            if (key.getType() != Protos.Key.Type.ORIGINAL && key.getType() != Protos.Key.Type.ENCRYPTED_SCRYPT_AES)
                continue;
            boolean encrypted = key.getType() == Protos.Key.Type.ENCRYPTED_SCRYPT_AES;
            byte[] priv = key.hasSecretBytes() ? key.getSecretBytes().toByteArray() : null;
            if (!key.hasPublicKey())
                throw new UnreadableWalletException("Public key missing");
            byte[] pub = key.getPublicKey().toByteArray();
            ECKey ecKey;
            if (encrypted) {
                checkState(keyCrypter != null, "This wallet is encrypted but encrypt() was not called prior to deserialization");
                if (!key.hasEncryptedData())
                    throw new UnreadableWalletException("Encrypted private key data missing");
                Protos.EncryptedData proto = key.getEncryptedData();
                EncryptedData e = new EncryptedData(proto.getInitialisationVector().toByteArray(),
                        proto.getEncryptedPrivateKey().toByteArray());
                ecKey = ECKey.fromEncrypted(e, keyCrypter, pub);
            } else {
                if (priv != null)
                    ecKey = ECKey.fromPrivateAndPrecalculatedPublic(priv, pub);
                else
                    ecKey = ECKey.fromPublicOnly(pub);
            }
            ecKey.setCreationTimeSeconds(key.getCreationTimestamp() / 1000);
            importKeyLocked(ecKey);
        }
    } finally {
        lock.unlock();
    }
}
 
Example 4
Source File: BasicKeyChain.java    From GreenBits with GNU General Public License v3.0 5 votes vote down vote up
private void deserializeFromProtobuf(List<Protos.Key> keys) throws UnreadableWalletException {
    lock.lock();
    try {
        checkState(hashToKeys.isEmpty(), "Tried to deserialize into a non-empty chain");
        for (Protos.Key key : keys) {
            if (key.getType() != Protos.Key.Type.ORIGINAL && key.getType() != Protos.Key.Type.ENCRYPTED_SCRYPT_AES)
                continue;
            boolean encrypted = key.getType() == Protos.Key.Type.ENCRYPTED_SCRYPT_AES;
            byte[] priv = key.hasSecretBytes() ? key.getSecretBytes().toByteArray() : null;
            if (!key.hasPublicKey())
                throw new UnreadableWalletException("Public key missing");
            byte[] pub = key.getPublicKey().toByteArray();
            ECKey ecKey;
            if (encrypted) {
                checkState(keyCrypter != null, "This wallet is encrypted but encrypt() was not called prior to deserialization");
                if (!key.hasEncryptedData())
                    throw new UnreadableWalletException("Encrypted private key data missing");
                Protos.EncryptedData proto = key.getEncryptedData();
                EncryptedData e = new EncryptedData(proto.getInitialisationVector().toByteArray(),
                        proto.getEncryptedPrivateKey().toByteArray());
                ecKey = ECKey.fromEncrypted(e, keyCrypter, pub);
            } else {
                if (priv != null)
                    ecKey = ECKey.fromPrivateAndPrecalculatedPublic(priv, pub);
                else
                    ecKey = ECKey.fromPublicOnly(pub);
            }
            ecKey.setCreationTimeSeconds(key.getCreationTimestamp() / 1000);
            importKeyLocked(ecKey);
        }
    } finally {
        lock.unlock();
    }
}
 
Example 5
Source File: WalletTest.java    From bcm-android with GNU General Public License v3.0 4 votes vote down vote up
@Test
public void keyRotationRandom() throws Exception {
    Utils.setMockClock();
    // Start with an empty wallet (no HD chain).
    wallet = new Wallet(UNITTEST);
    // Watch out for wallet-initiated broadcasts.
    MockTransactionBroadcaster broadcaster = new MockTransactionBroadcaster(wallet);
    // Send three cents to two different random keys, then add a key and mark the initial keys as compromised.
    ECKey key1 = new ECKey();
    key1.setCreationTimeSeconds(Utils.currentTimeSeconds() - (86400 * 2));
    ECKey key2 = new ECKey();
    key2.setCreationTimeSeconds(Utils.currentTimeSeconds() - 86400);
    wallet.importKey(key1);
    wallet.importKey(key2);
    sendMoneyToWallet(wallet, AbstractBlockChain.NewBlockType.BEST_CHAIN, CENT, LegacyAddress.fromKey(UNITTEST, key1));
    sendMoneyToWallet(wallet, AbstractBlockChain.NewBlockType.BEST_CHAIN, CENT, LegacyAddress.fromKey(UNITTEST, key2));
    sendMoneyToWallet(wallet, AbstractBlockChain.NewBlockType.BEST_CHAIN, CENT, LegacyAddress.fromKey(UNITTEST, key2));
    Date compromiseTime = Utils.now();
    assertEquals(0, broadcaster.size());
    assertFalse(wallet.isKeyRotating(key1));

    // We got compromised!
    Utils.rollMockClock(1);
    wallet.setKeyRotationTime(compromiseTime);
    assertTrue(wallet.isKeyRotating(key1));
    wallet.doMaintenance(null, true);

    Transaction tx = broadcaster.waitForTransactionAndSucceed();
    final Coin THREE_CENTS = CENT.add(CENT).add(CENT);
    assertEquals(Coin.valueOf(49100), tx.getFee());
    assertEquals(THREE_CENTS, tx.getValueSentFromMe(wallet));
    assertEquals(THREE_CENTS.subtract(tx.getFee()), tx.getValueSentToMe(wallet));
    // TX sends to one of our addresses (for now we ignore married wallets).
    final Address toAddress = tx.getOutput(0).getScriptPubKey().getToAddress(UNITTEST);
    final ECKey rotatingToKey = wallet.findKeyFromPubHash(toAddress.getHash());
    assertNotNull(rotatingToKey);
    assertFalse(wallet.isKeyRotating(rotatingToKey));
    assertEquals(3, tx.getInputs().size());
    // It confirms.
    sendMoneyToWallet(AbstractBlockChain.NewBlockType.BEST_CHAIN, tx);

    // Now receive some more money to the newly derived address via a new block and check that nothing happens.
    sendMoneyToWallet(wallet, AbstractBlockChain.NewBlockType.BEST_CHAIN, CENT, toAddress);
    assertTrue(wallet.doMaintenance(null, true).get().isEmpty());
    assertEquals(0, broadcaster.size());

    // Receive money via a new block on key1 and ensure it shows up as a maintenance task.
    sendMoneyToWallet(wallet, AbstractBlockChain.NewBlockType.BEST_CHAIN, CENT, LegacyAddress.fromKey(UNITTEST, key1));
    wallet.doMaintenance(null, true);
    tx = broadcaster.waitForTransactionAndSucceed();
    assertNotNull(wallet.findKeyFromPubHash(tx.getOutput(0).getScriptPubKey().getPubKeyHash()));
    log.info("Unexpected thing: {}", tx);
    assertEquals(Coin.valueOf(19300), tx.getFee());
    assertEquals(1, tx.getInputs().size());
    assertEquals(1, tx.getOutputs().size());
    assertEquals(CENT, tx.getValueSentFromMe(wallet));
    assertEquals(CENT.subtract(tx.getFee()), tx.getValueSentToMe(wallet));

    assertEquals(Transaction.Purpose.KEY_ROTATION, tx.getPurpose());

    // We don't attempt to race an attacker against unconfirmed transactions.

    // Now round-trip the wallet and check the protobufs are storing the data correctly.
    wallet = roundTrip(wallet);

    tx = wallet.getTransaction(tx.getHash());
    checkNotNull(tx);
    assertEquals(Transaction.Purpose.KEY_ROTATION, tx.getPurpose());
    // Have to divide here to avoid mismatch due to second-level precision in serialisation.
    assertEquals(compromiseTime.getTime() / 1000, wallet.getKeyRotationTime().getTime() / 1000);

    // Make a normal spend and check it's all ok.
    wallet.sendCoins(broadcaster, OTHER_ADDRESS, wallet.getBalance());
    tx = broadcaster.waitForTransaction();
    assertArrayEquals(OTHER_ADDRESS.getHash(), tx.getOutput(0).getScriptPubKey().getPubKeyHash());
}
 
Example 6
Source File: WalletTest.java    From bcm-android with GNU General Public License v3.0 4 votes vote down vote up
@SuppressWarnings("ConstantConditions")
@Test
public void keyRotationHD2() throws Exception {
    // Check we handle the following scenario: a weak random key is created, then some good random keys are created
    // but the weakness of the first isn't known yet. The wallet is upgraded to HD based on the weak key. Later, we
    // find out about the weakness and set the rotation time to after the bad key's creation date. A new HD chain
    // should be created based on the oldest known good key and the old chain + bad random key should rotate to it.

    // We fix the private keys just to make the test deterministic (last byte differs).
    Utils.setMockClock();
    ECKey badKey = ECKey.fromPrivate(Utils.HEX.decode("00905b93f990267f4104f316261fc10f9f983551f9ef160854f40102eb71cffdbb"));
    badKey.setCreationTimeSeconds(Utils.currentTimeSeconds());
    Utils.rollMockClock(86400);
    ECKey goodKey = ECKey.fromPrivate(Utils.HEX.decode("00905b93f990267f4104f316261fc10f9f983551f9ef160854f40102eb71cffdcc"));
    goodKey.setCreationTimeSeconds(Utils.currentTimeSeconds());

    // Do an upgrade based on the bad key.
    final AtomicReference<List<DeterministicKeyChain>> fChains = new AtomicReference<>();
    KeyChainGroup kcg = new KeyChainGroup(UNITTEST) {

        {
            fChains.set(chains);
        }
    };
    kcg.importKeys(badKey, goodKey);
    Utils.rollMockClock(86400);
    wallet = new Wallet(UNITTEST, kcg);   // This avoids the automatic HD initialisation
    assertTrue(fChains.get().isEmpty());
    wallet.upgradeToDeterministic(null);
    DeterministicKey badWatchingKey = wallet.getWatchingKey();
    assertEquals(badKey.getCreationTimeSeconds(), badWatchingKey.getCreationTimeSeconds());
    sendMoneyToWallet(wallet, AbstractBlockChain.NewBlockType.BEST_CHAIN, CENT, LegacyAddress.fromKey(UNITTEST, badWatchingKey));

    // Now we set the rotation time to the time we started making good keys. This should create a new HD chain.
    wallet.setKeyRotationTime(goodKey.getCreationTimeSeconds());
    List<Transaction> txns = wallet.doMaintenance(null, false).get();
    assertEquals(1, txns.size());
    Address output = txns.get(0).getOutput(0).getScriptPubKey().getToAddress(UNITTEST);
    ECKey usedKey = wallet.findKeyFromPubHash(output.getHash());
    assertEquals(goodKey.getCreationTimeSeconds(), usedKey.getCreationTimeSeconds());
    assertEquals(goodKey.getCreationTimeSeconds(), wallet.freshReceiveKey().getCreationTimeSeconds());
    assertEquals("mrM3TpCnav5YQuVA1xLercCGJH4DXujMtv", LegacyAddress.fromKey(UNITTEST, usedKey).toString());
    DeterministicKeyChain c = fChains.get().get(1);
    assertEquals(c.getEarliestKeyCreationTime(), goodKey.getCreationTimeSeconds());
    assertEquals(2, fChains.get().size());

    // Commit the maint txns.
    wallet.commitTx(txns.get(0));

    // Check next maintenance does nothing.
    assertTrue(wallet.doMaintenance(null, false).get().isEmpty());
    assertEquals(c, fChains.get().get(1));
    assertEquals(2, fChains.get().size());
}
 
Example 7
Source File: WalletTest.java    From green_android with GNU General Public License v3.0 4 votes vote down vote up
@SuppressWarnings("ConstantConditions")
@Test
public void keyRotationHD2() throws Exception {
    // Check we handle the following scenario: a weak random key is created, then some good random keys are created
    // but the weakness of the first isn't known yet. The wallet is upgraded to HD based on the weak key. Later, we
    // find out about the weakness and set the rotation time to after the bad key's creation date. A new HD chain
    // should be created based on the oldest known good key and the old chain + bad random key should rotate to it.

    // We fix the private keys just to make the test deterministic (last byte differs).
    Utils.setMockClock();
    ECKey badKey = ECKey.fromPrivate(Utils.HEX.decode("00905b93f990267f4104f316261fc10f9f983551f9ef160854f40102eb71cffdbb"));
    badKey.setCreationTimeSeconds(Utils.currentTimeSeconds());
    Utils.rollMockClock(86400);
    ECKey goodKey = ECKey.fromPrivate(Utils.HEX.decode("00905b93f990267f4104f316261fc10f9f983551f9ef160854f40102eb71cffdcc"));
    goodKey.setCreationTimeSeconds(Utils.currentTimeSeconds());

    // Do an upgrade based on the bad key.
    final AtomicReference<List<DeterministicKeyChain>> fChains = new AtomicReference<>();
    KeyChainGroup kcg = new KeyChainGroup(PARAMS) {

        {
            fChains.set(chains);
        }
    };
    kcg.importKeys(badKey, goodKey);
    Utils.rollMockClock(86400);
    wallet = new Wallet(PARAMS, kcg);   // This avoids the automatic HD initialisation
    assertTrue(fChains.get().isEmpty());
    wallet.upgradeToDeterministic(null);
    DeterministicKey badWatchingKey = wallet.getWatchingKey();
    assertEquals(badKey.getCreationTimeSeconds(), badWatchingKey.getCreationTimeSeconds());
    sendMoneyToWallet(wallet, AbstractBlockChain.NewBlockType.BEST_CHAIN, CENT, badWatchingKey.toAddress(PARAMS));

    // Now we set the rotation time to the time we started making good keys. This should create a new HD chain.
    wallet.setKeyRotationTime(goodKey.getCreationTimeSeconds());
    List<Transaction> txns = wallet.doMaintenance(null, false).get();
    assertEquals(1, txns.size());
    Address output = txns.get(0).getOutput(0).getAddressFromP2PKHScript(PARAMS);
    ECKey usedKey = wallet.findKeyFromPubHash(output.getHash160());
    assertEquals(goodKey.getCreationTimeSeconds(), usedKey.getCreationTimeSeconds());
    assertEquals(goodKey.getCreationTimeSeconds(), wallet.freshReceiveKey().getCreationTimeSeconds());
    assertEquals("mrM3TpCnav5YQuVA1xLercCGJH4DXujMtv", usedKey.toAddress(PARAMS).toString());
    DeterministicKeyChain c = fChains.get().get(1);
    assertEquals(c.getEarliestKeyCreationTime(), goodKey.getCreationTimeSeconds());
    assertEquals(2, fChains.get().size());

    // Commit the maint txns.
    wallet.commitTx(txns.get(0));

    // Check next maintenance does nothing.
    assertTrue(wallet.doMaintenance(null, false).get().isEmpty());
    assertEquals(c, fChains.get().get(1));
    assertEquals(2, fChains.get().size());
}
 
Example 8
Source File: WalletTest.java    From GreenBits with GNU General Public License v3.0 4 votes vote down vote up
@SuppressWarnings("ConstantConditions")
@Test
public void keyRotationHD2() throws Exception {
    // Check we handle the following scenario: a weak random key is created, then some good random keys are created
    // but the weakness of the first isn't known yet. The wallet is upgraded to HD based on the weak key. Later, we
    // find out about the weakness and set the rotation time to after the bad key's creation date. A new HD chain
    // should be created based on the oldest known good key and the old chain + bad random key should rotate to it.

    // We fix the private keys just to make the test deterministic (last byte differs).
    Utils.setMockClock();
    ECKey badKey = ECKey.fromPrivate(Utils.HEX.decode("00905b93f990267f4104f316261fc10f9f983551f9ef160854f40102eb71cffdbb"));
    badKey.setCreationTimeSeconds(Utils.currentTimeSeconds());
    Utils.rollMockClock(86400);
    ECKey goodKey = ECKey.fromPrivate(Utils.HEX.decode("00905b93f990267f4104f316261fc10f9f983551f9ef160854f40102eb71cffdcc"));
    goodKey.setCreationTimeSeconds(Utils.currentTimeSeconds());

    // Do an upgrade based on the bad key.
    final AtomicReference<List<DeterministicKeyChain>> fChains = new AtomicReference<>();
    KeyChainGroup kcg = new KeyChainGroup(PARAMS) {

        {
            fChains.set(chains);
        }
    };
    kcg.importKeys(badKey, goodKey);
    Utils.rollMockClock(86400);
    wallet = new Wallet(PARAMS, kcg);   // This avoids the automatic HD initialisation
    assertTrue(fChains.get().isEmpty());
    wallet.upgradeToDeterministic(null);
    DeterministicKey badWatchingKey = wallet.getWatchingKey();
    assertEquals(badKey.getCreationTimeSeconds(), badWatchingKey.getCreationTimeSeconds());
    sendMoneyToWallet(wallet, AbstractBlockChain.NewBlockType.BEST_CHAIN, CENT, badWatchingKey.toAddress(PARAMS));

    // Now we set the rotation time to the time we started making good keys. This should create a new HD chain.
    wallet.setKeyRotationTime(goodKey.getCreationTimeSeconds());
    List<Transaction> txns = wallet.doMaintenance(null, false).get();
    assertEquals(1, txns.size());
    Address output = txns.get(0).getOutput(0).getAddressFromP2PKHScript(PARAMS);
    ECKey usedKey = wallet.findKeyFromPubHash(output.getHash160());
    assertEquals(goodKey.getCreationTimeSeconds(), usedKey.getCreationTimeSeconds());
    assertEquals(goodKey.getCreationTimeSeconds(), wallet.freshReceiveKey().getCreationTimeSeconds());
    assertEquals("mrM3TpCnav5YQuVA1xLercCGJH4DXujMtv", usedKey.toAddress(PARAMS).toString());
    DeterministicKeyChain c = fChains.get().get(1);
    assertEquals(c.getEarliestKeyCreationTime(), goodKey.getCreationTimeSeconds());
    assertEquals(2, fChains.get().size());

    // Commit the maint txns.
    wallet.commitTx(txns.get(0));

    // Check next maintenance does nothing.
    assertTrue(wallet.doMaintenance(null, false).get().isEmpty());
    assertEquals(c, fChains.get().get(1));
    assertEquals(2, fChains.get().size());
}