Search in sources :

Example 16 with ECKey

use of com.sparrowwallet.drongo.crypto.ECKey in project sparrow by sparrowwallet.

the class MessageSignDialog method verifyMessage.

private void verifyMessage() {
    try {
        // Find ECKey from message and signature
        // http://www.secg.org/download/aid-780/sec1-v2.pdf section 4.1.6
        boolean verified = false;
        try {
            ECKey signedMessageKey = ECKey.signedMessageToKey(message.getText().trim(), signature.getText().trim(), false);
            verified = verifyMessage(signedMessageKey);
        } catch (SignatureException e) {
        // ignore
        }
        if (!verified) {
            try {
                ECKey electrumSignedMessageKey = ECKey.signedMessageToKey(message.getText(), signature.getText(), true);
                verified = verifyMessage(electrumSignedMessageKey);
            } catch (SignatureException e) {
            // ignore
            }
        }
        if (verified) {
            Alert alert = new Alert(Alert.AlertType.INFORMATION);
            AppServices.setStageIcon(alert.getDialogPane().getScene().getWindow());
            alert.setTitle("Verification Succeeded");
            alert.setHeaderText("Verification Succeeded");
            alert.setContentText("The signature verified against the message.");
            AppServices.moveToActiveWindowScreen(alert);
            alert.showAndWait();
        } else {
            AppServices.showErrorDialog("Verification failed", "The provided signature did not match the message for this address.");
        }
    } catch (IllegalArgumentException e) {
        AppServices.showErrorDialog("Could not verify message", e.getMessage());
    } catch (Exception e) {
        log.error("Could not verify message", e);
        AppServices.showErrorDialog("Could not verify message", e.getMessage());
    }
}
Also used : ECKey(com.sparrowwallet.drongo.crypto.ECKey) SignatureException(java.security.SignatureException) InvalidAddressException(com.sparrowwallet.drongo.address.InvalidAddressException) SignatureException(java.security.SignatureException)

Example 17 with ECKey

use of com.sparrowwallet.drongo.crypto.ECKey in project sparrow by sparrowwallet.

the class MessageSignDialog method signUnencryptedKeystore.

private void signUnencryptedKeystore(Wallet decryptedWallet) {
    try {
        Keystore keystore = decryptedWallet.getKeystores().get(0);
        ECKey privKey = keystore.getKey(walletNode);
        ScriptType scriptType = electrumSignatureFormat ? ScriptType.P2PKH : decryptedWallet.getScriptType();
        String signatureText = privKey.signMessage(message.getText().trim(), scriptType);
        signature.clear();
        signature.appendText(signatureText);
        privKey.clear();
    } catch (Exception e) {
        log.error("Could not sign message", e);
        AppServices.showErrorDialog("Could not sign message", e.getMessage());
    }
}
Also used : Keystore(com.sparrowwallet.drongo.wallet.Keystore) ScriptType(com.sparrowwallet.drongo.protocol.ScriptType) ECKey(com.sparrowwallet.drongo.crypto.ECKey) SecureString(com.sparrowwallet.drongo.SecureString) InvalidAddressException(com.sparrowwallet.drongo.address.InvalidAddressException) SignatureException(java.security.SignatureException)

Example 18 with ECKey

use of com.sparrowwallet.drongo.crypto.ECKey in project sparrow by sparrowwallet.

the class PrivateKeySweepDialog method createTransaction.

private void createTransaction(ECKey privKey, ScriptType scriptType, List<TransactionOutput> txOutputs, Address destAddress) {
    ECKey pubKey = ECKey.fromPublicOnly(privKey);
    Transaction noFeeTransaction = new Transaction();
    long total = 0;
    for (TransactionOutput txOutput : txOutputs) {
        scriptType.addSpendingInput(noFeeTransaction, txOutput, pubKey, TransactionSignature.dummy(scriptType == P2TR ? TransactionSignature.Type.SCHNORR : TransactionSignature.Type.ECDSA));
        total += txOutput.getValue();
    }
    TransactionOutput sweepOutput = new TransactionOutput(noFeeTransaction, total, destAddress.getOutputScript());
    noFeeTransaction.addOutput(sweepOutput);
    Double feeRate = AppServices.getDefaultFeeRate();
    long fee = (long) Math.ceil(noFeeTransaction.getVirtualSize() * feeRate);
    if (feeRate == Transaction.DEFAULT_MIN_RELAY_FEE) {
        fee++;
    }
    long dustThreshold = destAddress.getScriptType().getDustThreshold(sweepOutput, Transaction.DUST_RELAY_TX_FEE);
    if (total - fee <= dustThreshold) {
        AppServices.showErrorDialog("Insufficient funds", "The unspent outputs for this private key contain insufficient funds to spend (" + total + " sats).");
        return;
    }
    Transaction transaction = new Transaction();
    transaction.setVersion(2);
    transaction.setLocktime(AppServices.getCurrentBlockHeight() == null ? 0 : AppServices.getCurrentBlockHeight());
    for (TransactionInput txInput : noFeeTransaction.getInputs()) {
        transaction.addInput(txInput);
    }
    transaction.addOutput(new TransactionOutput(transaction, total - fee, destAddress.getOutputScript()));
    PSBT psbt = new PSBT(transaction);
    for (int i = 0; i < txOutputs.size(); i++) {
        TransactionOutput utxoOutput = txOutputs.get(i);
        TransactionInput txInput = transaction.getInputs().get(i);
        PSBTInput psbtInput = psbt.getPsbtInputs().get(i);
        psbtInput.setWitnessUtxo(utxoOutput);
        if (ScriptType.P2SH.isScriptType(utxoOutput.getScript())) {
            psbtInput.setRedeemScript(txInput.getScriptSig().getFirstNestedScript());
        }
        if (txInput.getWitness() != null) {
            psbtInput.setWitnessScript(txInput.getWitness().getWitnessScript());
        }
        if (!psbtInput.sign(scriptType.getOutputKey(privKey))) {
            AppServices.showErrorDialog("Failed to sign", "Failed to sign for transaction output " + utxoOutput.getHash() + ":" + utxoOutput.getIndex());
            return;
        }
        TransactionSignature signature = psbtInput.isTaproot() ? psbtInput.getTapKeyPathSignature() : psbtInput.getPartialSignature(pubKey);
        Transaction finalizeTransaction = new Transaction();
        TransactionInput finalizedTxInput = scriptType.addSpendingInput(finalizeTransaction, utxoOutput, pubKey, signature);
        psbtInput.setFinalScriptSig(finalizedTxInput.getScriptSig());
        psbtInput.setFinalScriptWitness(finalizedTxInput.getWitness());
    }
    setResult(psbt.extractTransaction());
}
Also used : PSBT(com.sparrowwallet.drongo.psbt.PSBT) ECKey(com.sparrowwallet.drongo.crypto.ECKey) PSBTInput(com.sparrowwallet.drongo.psbt.PSBTInput)

Example 19 with ECKey

use of com.sparrowwallet.drongo.crypto.ECKey in project sparrow by sparrowwallet.

the class DbPersistence method loadWallet.

@Override
public WalletAndKey loadWallet(Storage storage, CharSequence password, ECKey alreadyDerivedKey) throws IOException, StorageException {
    ECKey encryptionKey = getEncryptionKey(password, storage.getWalletFile(), alreadyDerivedKey);
    migrate(storage, MASTER_SCHEMA, encryptionKey);
    Jdbi jdbi = getJdbi(storage, getFilePassword(encryptionKey));
    masterWallet = jdbi.withHandle(handle -> {
        WalletDao walletDao = handle.attach(WalletDao.class);
        return walletDao.getMainWallet(MASTER_SCHEMA);
    });
    Map<WalletAndKey, Storage> childWallets = loadChildWallets(storage, masterWallet, encryptionKey);
    masterWallet.setChildWallets(childWallets.keySet().stream().map(WalletAndKey::getWallet).collect(Collectors.toList()));
    createUpdateExecutor(masterWallet);
    return new WalletAndKey(masterWallet, encryptionKey, keyDeriver, childWallets);
}
Also used : java.util(java.util) FlywayException(org.flywaydb.core.api.FlywayException) AsymmetricKeyDeriver(com.sparrowwallet.drongo.crypto.AsymmetricKeyDeriver) com.sparrowwallet.drongo.wallet(com.sparrowwallet.drongo.wallet) LoggerFactory(org.slf4j.LoggerFactory) ByteBuffer(java.nio.ByteBuffer) StandardCopyOption(java.nio.file.StandardCopyOption) SecureRandom(java.security.SecureRandom) Files(com.google.common.io.Files) Utils(com.sparrowwallet.drongo.Utils) InvalidPasswordException(com.sparrowwallet.drongo.crypto.InvalidPasswordException) Subscribe(com.google.common.eventbus.Subscribe) H2DatabasePlugin(org.jdbi.v3.core.h2.H2DatabasePlugin) ExecutorService(java.util.concurrent.ExecutorService) com.sparrowwallet.sparrow.wallet(com.sparrowwallet.sparrow.wallet) Jdbi(org.jdbi.v3.core.Jdbi) Argon2KeyDeriver(com.sparrowwallet.drongo.crypto.Argon2KeyDeriver) SqlObjectPlugin(org.jdbi.v3.sqlobject.SqlObjectPlugin) Logger(org.slf4j.Logger) com.sparrowwallet.sparrow.event(com.sparrowwallet.sparrow.event) BasicThreadFactory(org.apache.commons.lang3.concurrent.BasicThreadFactory) Collectors(java.util.stream.Collectors) StandardCharsets(java.nio.charset.StandardCharsets) Executors(java.util.concurrent.Executors) ChangeFileEncryption(org.h2.tools.ChangeFileEncryption) TimeUnit(java.util.concurrent.TimeUnit) HikariConfig(com.zaxxer.hikari.HikariConfig) Stream(java.util.stream.Stream) java.io(java.io) com.sparrowwallet.sparrow.io(com.sparrowwallet.sparrow.io) HikariDataSource(com.zaxxer.hikari.HikariDataSource) EventManager(com.sparrowwallet.sparrow.EventManager) ECKey(com.sparrowwallet.drongo.crypto.ECKey) Flyway(org.flywaydb.core.Flyway) Sha256Hash(com.sparrowwallet.drongo.protocol.Sha256Hash) HikariPool(com.zaxxer.hikari.pool.HikariPool) FlywayValidateException(org.flywaydb.core.api.exception.FlywayValidateException) FileChannel(java.nio.channels.FileChannel) Jdbi(org.jdbi.v3.core.Jdbi) ECKey(com.sparrowwallet.drongo.crypto.ECKey)

Example 20 with ECKey

use of com.sparrowwallet.drongo.crypto.ECKey in project sparrow by sparrowwallet.

the class PayNymController method addWalletIfNotificationTransactionPresent.

private void addWalletIfNotificationTransactionPresent(Wallet decryptedWallet, Map<BlockTransaction, PayNym> unlinkedPayNyms, Map<BlockTransaction, WalletNode> unlinkedNotifications) {
    List<Wallet> addedWallets = new ArrayList<>();
    for (BlockTransaction blockTransaction : unlinkedNotifications.keySet()) {
        try {
            PayNym payNym = unlinkedPayNyms.get(blockTransaction);
            PaymentCode externalPaymentCode = payNym.paymentCode();
            WalletNode input0Node = unlinkedNotifications.get(blockTransaction);
            Keystore keystore = input0Node.getWallet().isNested() ? decryptedWallet.getChildWallet(input0Node.getWallet().getName()).getKeystores().get(0) : decryptedWallet.getKeystores().get(0);
            ECKey input0Key = keystore.getKey(input0Node);
            TransactionOutPoint input0Outpoint = PaymentCode.getDesignatedInput(blockTransaction.getTransaction()).getOutpoint();
            SecretPoint secretPoint = new SecretPoint(input0Key.getPrivKeyBytes(), externalPaymentCode.getNotificationKey().getPubKey());
            byte[] blindingMask = PaymentCode.getMask(secretPoint.ECDHSecretAsBytes(), input0Outpoint.bitcoinSerialize());
            byte[] blindedPaymentCode = PaymentCode.blind(getMasterWallet().getPaymentCode().getPayload(), blindingMask);
            byte[] opReturnData = PaymentCode.getOpReturnData(blockTransaction.getTransaction());
            if (Arrays.equals(opReturnData, blindedPaymentCode)) {
                addedWallets.addAll(addChildWallets(payNym, externalPaymentCode));
            } else {
                blockTransaction.setLabel(INVALID_PAYMENT_CODE_LABEL);
                EventManager.get().post(new WalletEntryLabelsChangedEvent(input0Node.getWallet(), new TransactionEntry(input0Node.getWallet(), blockTransaction, Collections.emptyMap(), Collections.emptyMap())));
            }
        } catch (Exception e) {
            log.error("Error adding linked contact from notification transaction", e);
        }
    }
    if (!addedWallets.isEmpty()) {
        Wallet masterWallet = getMasterWallet();
        Storage storage = AppServices.get().getOpenWallets().get(masterWallet);
        EventManager.get().post(new ChildWalletsAddedEvent(storage, masterWallet, addedWallets));
        followingList.refresh();
    }
}
Also used : PaymentCode(com.sparrowwallet.drongo.bip47.PaymentCode) ECKey(com.sparrowwallet.drongo.crypto.ECKey) Storage(com.sparrowwallet.sparrow.io.Storage) TransactionEntry(com.sparrowwallet.sparrow.wallet.TransactionEntry) SecretPoint(com.sparrowwallet.drongo.bip47.SecretPoint)

Aggregations

ECKey (com.sparrowwallet.drongo.crypto.ECKey)45 Test (org.junit.Test)22 ByteArrayOutputStream (java.io.ByteArrayOutputStream)7 Address (com.sparrowwallet.drongo.address.Address)6 ChildNumber (com.sparrowwallet.drongo.crypto.ChildNumber)6 PaymentCode (com.sparrowwallet.drongo.bip47.PaymentCode)5 PSBT (com.sparrowwallet.drongo.psbt.PSBT)5 PSBTInput (com.sparrowwallet.drongo.psbt.PSBTInput)5 InvalidAddressException (com.sparrowwallet.drongo.address.InvalidAddressException)4 ScriptType (com.sparrowwallet.drongo.protocol.ScriptType)4 SecureString (com.sparrowwallet.drongo.SecureString)3 SecretPoint (com.sparrowwallet.drongo.bip47.SecretPoint)3 DeterministicKey (com.sparrowwallet.drongo.crypto.DeterministicKey)3 SchnorrSignature (com.sparrowwallet.drongo.crypto.SchnorrSignature)3 PSBTOutput (com.sparrowwallet.drongo.psbt.PSBTOutput)3 StandardCharsets (java.nio.charset.StandardCharsets)3 java.util (java.util)3 Collectors (java.util.stream.Collectors)3 Subscribe (com.google.common.eventbus.Subscribe)2 Files (com.google.common.io.Files)2