From 4d61585e4ce9fb346a44a875de47e9d5ff1cebe2 Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Mon, 8 Feb 2021 11:04:57 +0200 Subject: [PATCH 001/155] rbf: remove unnecessary locktime = 0 check --- .../java/com/sparrowwallet/drongo/protocol/Transaction.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/main/java/com/sparrowwallet/drongo/protocol/Transaction.java b/src/main/java/com/sparrowwallet/drongo/protocol/Transaction.java index 2dc71e9..e7c7f22 100644 --- a/src/main/java/com/sparrowwallet/drongo/protocol/Transaction.java +++ b/src/main/java/com/sparrowwallet/drongo/protocol/Transaction.java @@ -89,8 +89,6 @@ public class Transaction extends ChildMessage { } public boolean isReplaceByFee() { - if(locktime == 0) return false; - for(TransactionInput input : inputs) { if(input.isReplaceByFeeEnabled()) { return true; From 44b29b2b7b6cb849f645ce9db7af18691b438553 Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Mon, 8 Feb 2021 18:17:11 +0200 Subject: [PATCH 002/155] add blue wallet --- .../java/com/sparrowwallet/drongo/wallet/WalletModel.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/WalletModel.java b/src/main/java/com/sparrowwallet/drongo/wallet/WalletModel.java index 9273d8a..e71b676 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/WalletModel.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/WalletModel.java @@ -1,7 +1,7 @@ package com.sparrowwallet.drongo.wallet; public enum WalletModel { - SEED, SPARROW, BITCOIN_CORE, ELECTRUM, TREZOR_1, TREZOR_T, COLDCARD, LEDGER_NANO_S, LEDGER_NANO_X, DIGITALBITBOX_01, KEEPKEY, SPECTER_DESKTOP, COBO_VAULT, BITBOX_02, SPECTER_DIY, PASSPORT; + SEED, SPARROW, BITCOIN_CORE, ELECTRUM, TREZOR_1, TREZOR_T, COLDCARD, LEDGER_NANO_S, LEDGER_NANO_X, DIGITALBITBOX_01, KEEPKEY, SPECTER_DESKTOP, COBO_VAULT, BITBOX_02, SPECTER_DIY, PASSPORT, BLUE_WALLET; public static WalletModel getModel(String model) { return valueOf(model.toUpperCase()); @@ -32,6 +32,10 @@ public enum WalletModel { return "specter"; } + if(this == BLUE_WALLET) { + return "bluewallet"; + } + return this.toString().toLowerCase(); } From 3882a4b4bd9a738329bfffcaff72b477bb3a2d2f Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Tue, 9 Feb 2021 17:31:26 +0200 Subject: [PATCH 003/155] support wallet labels copying from past wallets --- .../drongo/wallet/BlockTransaction.java | 6 +++- .../drongo/wallet/BlockTransactionHash.java | 3 +- .../wallet/BlockTransactionHashIndex.java | 8 ++++-- .../drongo/wallet/WalletNode.java | 28 +++++++++++++++++++ 4 files changed, 41 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/BlockTransaction.java b/src/main/java/com/sparrowwallet/drongo/wallet/BlockTransaction.java index 53036c6..5f0705a 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/BlockTransaction.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/BlockTransaction.java @@ -18,7 +18,11 @@ public class BlockTransaction extends BlockTransactionHash implements Comparable } public BlockTransaction(Sha256Hash hash, int height, Date date, Long fee, Transaction transaction, Sha256Hash blockHash) { - super(hash, height, date, fee); + this(hash, height, date, fee, transaction, blockHash, null); + } + + public BlockTransaction(Sha256Hash hash, int height, Date date, Long fee, Transaction transaction, Sha256Hash blockHash, String label) { + super(hash, height, date, fee, label); this.transaction = transaction; this.blockHash = blockHash; } diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/BlockTransactionHash.java b/src/main/java/com/sparrowwallet/drongo/wallet/BlockTransactionHash.java index 4717f34..09af7c2 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/BlockTransactionHash.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/BlockTransactionHash.java @@ -16,11 +16,12 @@ public abstract class BlockTransactionHash { private String label; - public BlockTransactionHash(Sha256Hash hash, int height, Date date, Long fee) { + public BlockTransactionHash(Sha256Hash hash, int height, Date date, Long fee, String label) { this.hash = hash; this.height = height; this.date = date; this.fee = fee; + this.label = label; } public Sha256Hash getHash() { diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/BlockTransactionHashIndex.java b/src/main/java/com/sparrowwallet/drongo/wallet/BlockTransactionHashIndex.java index 0368755..2046c38 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/BlockTransactionHashIndex.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/BlockTransactionHashIndex.java @@ -16,7 +16,11 @@ public class BlockTransactionHashIndex extends BlockTransactionHash implements C } public BlockTransactionHashIndex(Sha256Hash hash, int height, Date date, Long fee, long index, long value, BlockTransactionHashIndex spentBy) { - super(hash, height, date, fee); + this(hash, height, date, fee, index, value, spentBy, null); + } + + public BlockTransactionHashIndex(Sha256Hash hash, int height, Date date, Long fee, long index, long value, BlockTransactionHashIndex spentBy, String label) { + super(hash, height, date, fee, label); this.index = index; this.value = value; this.spentBy = spentBy; @@ -92,6 +96,6 @@ public class BlockTransactionHashIndex extends BlockTransactionHash implements C } public BlockTransactionHashIndex copy() { - return new BlockTransactionHashIndex(super.getHash(), super.getHeight(), super.getDate(), super.getFee(), index, value, spentBy == null ? null : spentBy.copy()); + return new BlockTransactionHashIndex(super.getHash(), super.getHeight(), super.getDate(), super.getFee(), index, value, spentBy == null ? null : spentBy.copy(), super.getLabel()); } } diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/WalletNode.java b/src/main/java/com/sparrowwallet/drongo/wallet/WalletNode.java index 0725a68..792d7f8 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/WalletNode.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/WalletNode.java @@ -207,4 +207,32 @@ public class WalletNode implements Comparable { return copy; } + + public void copyLabels(WalletNode pastNode) { + if(pastNode == null) { + return; + } + + if(label == null && pastNode.label != null) { + label = pastNode.label; + } + + for(BlockTransactionHashIndex txo : getTransactionOutputs()) { + Optional optPastTxo = pastNode.getTransactionOutputs().stream().filter(pastTxo -> pastTxo.equals(txo)).findFirst(); + if(optPastTxo.isPresent()) { + BlockTransactionHashIndex pastTxo = optPastTxo.get(); + if(txo.getLabel() == null && pastTxo.getLabel() != null) { + txo.setLabel(pastTxo.getLabel()); + } + if(txo.isSpent() && pastTxo.isSpent() && txo.getSpentBy().getLabel() == null && pastTxo.getSpentBy().getLabel() != null) { + txo.getSpentBy().setLabel(pastTxo.getSpentBy().getLabel()); + } + } + } + + for(WalletNode childNode : getChildren()) { + Optional optPastChildNode = pastNode.getChildren().stream().filter(node -> node.equals(childNode)).findFirst(); + optPastChildNode.ifPresent(childNode::copyLabels); + } + } } From 79216fac912724e7b06b3ffe15e38ddf005e665f Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Wed, 17 Feb 2021 10:23:49 +0200 Subject: [PATCH 004/155] add descriptions to script types --- .../drongo/protocol/ScriptType.java | 24 ++++++++++++------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/src/main/java/com/sparrowwallet/drongo/protocol/ScriptType.java b/src/main/java/com/sparrowwallet/drongo/protocol/ScriptType.java index 5428b1c..d74d50e 100644 --- a/src/main/java/com/sparrowwallet/drongo/protocol/ScriptType.java +++ b/src/main/java/com/sparrowwallet/drongo/protocol/ScriptType.java @@ -17,7 +17,7 @@ import static com.sparrowwallet.drongo.protocol.ScriptOpCodes.*; import static com.sparrowwallet.drongo.protocol.Transaction.WITNESS_SCALE_FACTOR; public enum ScriptType { - P2PK("P2PK", "m/44'/0'/0'") { + P2PK("P2PK", "Legacy (P2PK)", "m/44'/0'/0'") { @Override public Address getAddress(byte[] pubKey) { return new P2PKAddress(pubKey); @@ -131,7 +131,7 @@ public enum ScriptType { return List.of(SINGLE); } }, - P2PKH("P2PKH", "m/44'/0'/0'") { + P2PKH("P2PKH", "Legacy (P2PKH)", "m/44'/0'/0'") { @Override public Address getAddress(byte[] pubKeyHash) { return new P2PKHAddress(pubKeyHash); @@ -244,7 +244,7 @@ public enum ScriptType { return List.of(SINGLE); } }, - MULTISIG("Bare Multisig", "m/44'/0'/0'") { + MULTISIG("Bare Multisig", "Bare Multisig", "m/44'/0'/0'") { @Override public Address getAddress(byte[] bytes) { throw new ProtocolException("No single address for multisig script type"); @@ -430,7 +430,7 @@ public enum ScriptType { return List.of(MULTI); } }, - P2SH("P2SH", "m/45'") { + P2SH("P2SH", "Legacy (P2SH)", "m/45'") { @Override public Address getAddress(byte[] scriptHash) { return new P2SHAddress(scriptHash); @@ -555,7 +555,7 @@ public enum ScriptType { return List.of(MULTI); } }, - P2SH_P2WPKH("P2SH-P2WPKH", "m/49'/0'/0'") { + P2SH_P2WPKH("P2SH-P2WPKH", "Nested Segwit (P2SH-P2WSH)", "m/49'/0'/0'") { @Override public Address getAddress(byte[] scriptHash) { return P2SH.getAddress(scriptHash); @@ -658,7 +658,7 @@ public enum ScriptType { return List.of(SINGLE); } }, - P2SH_P2WSH("P2SH-P2WSH", "m/48'/0'/0'/1'") { + P2SH_P2WSH("P2SH-P2WSH", "Nested Segwit (P2SH-P2WSH)", "m/48'/0'/0'/1'") { @Override public Address getAddress(byte[] scriptHash) { return P2SH.getAddress(scriptHash); @@ -759,7 +759,7 @@ public enum ScriptType { return List.of(MULTI, CUSTOM); } }, - P2WPKH("P2WPKH", "m/84'/0'/0'") { + P2WPKH("P2WPKH", "Native Segwit (P2WPKH)", "m/84'/0'/0'") { @Override public Address getAddress(byte[] pubKeyHash) { return new P2WPKHAddress(pubKeyHash); @@ -864,7 +864,7 @@ public enum ScriptType { return List.of(SINGLE); } }, - P2WSH("P2WSH", "m/48'/0'/0'/2'") { + P2WSH("P2WSH", "Native Segwit (P2WSH)", "m/48'/0'/0'/2'") { @Override public Address getAddress(byte[] scriptHash) { return new P2WSHAddress(scriptHash); @@ -977,10 +977,12 @@ public enum ScriptType { }; private final String name; + private final String description; private final String defaultDerivationPath; - ScriptType(String name, String defaultDerivationPath) { + ScriptType(String name, String description, String defaultDerivationPath) { this.name = name; + this.description = description; this.defaultDerivationPath = defaultDerivationPath; } @@ -988,6 +990,10 @@ public enum ScriptType { return name; } + public String getDescription() { + return description; + } + public String getDefaultDerivationPath() { return Network.get() != Network.MAINNET ? defaultDerivationPath.replace("/0'/0'", "/1'/0'") : defaultDerivationPath; } From fe91063e8fa5acb967907c6e1f65b21e7bca0375 Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Mon, 22 Feb 2021 16:04:34 +0200 Subject: [PATCH 005/155] add system property to disable script type derivation validation --- src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java index 252d5c7..e17f7c7 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java @@ -21,6 +21,7 @@ import static com.sparrowwallet.drongo.protocol.Transaction.WITNESS_SCALE_FACTOR public class Wallet { public static final int DEFAULT_LOOKAHEAD = 20; + public static final String ALLOW_DERIVATIONS_MATCHING_OTHER_SCRIPT_TYPES_PROPERTY = "com.sparrowwallet.allowDerivationsMatchingOtherScriptTypes"; private String name; private Network network = Network.get(); @@ -980,6 +981,10 @@ public class Wallet { } public boolean derivationMatchesAnotherScriptType(String derivationPath) { + if(Boolean.TRUE.toString().equals(System.getProperty(ALLOW_DERIVATIONS_MATCHING_OTHER_SCRIPT_TYPES_PROPERTY))) { + return false; + } + if(scriptType != null && scriptType.getAccount(derivationPath) > -1) { return false; } From 08acfe5ba16ed54ebbdcb8177cea88e4c53bda77 Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Wed, 24 Feb 2021 13:38:47 +0200 Subject: [PATCH 006/155] add signet support --- src/main/java/com/sparrowwallet/drongo/ExtendedKey.java | 2 +- src/main/java/com/sparrowwallet/drongo/Network.java | 3 ++- .../java/com/sparrowwallet/drongo/address/AddressTest.java | 4 ++++ 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/sparrowwallet/drongo/ExtendedKey.java b/src/main/java/com/sparrowwallet/drongo/ExtendedKey.java index adb7a10..37efd09 100644 --- a/src/main/java/com/sparrowwallet/drongo/ExtendedKey.java +++ b/src/main/java/com/sparrowwallet/drongo/ExtendedKey.java @@ -206,7 +206,7 @@ public class ExtendedKey { } public static List
getHeaders(Network network) { - return Arrays.stream(Header.values()).filter(header -> header.getNetwork() == network || (header.getNetwork() == Network.TESTNET && network == Network.REGTEST)).collect(Collectors.toList()); + return Arrays.stream(Header.values()).filter(header -> header.getNetwork() == network || (header.getNetwork() == Network.TESTNET && network == Network.REGTEST) || (header.getNetwork() == Network.TESTNET && network == Network.SIGNET)).collect(Collectors.toList()); } public static Header fromExtendedKey(String xkey) { diff --git a/src/main/java/com/sparrowwallet/drongo/Network.java b/src/main/java/com/sparrowwallet/drongo/Network.java index ab389ac..06c6917 100644 --- a/src/main/java/com/sparrowwallet/drongo/Network.java +++ b/src/main/java/com/sparrowwallet/drongo/Network.java @@ -3,7 +3,8 @@ package com.sparrowwallet.drongo; public enum Network { MAINNET("mainnet", 0, "1", 5, "3", "bc", ExtendedKey.Header.xprv, ExtendedKey.Header.xpub, 8332), TESTNET("testnet", 111, "mn", 196, "2", "tb", ExtendedKey.Header.tprv, ExtendedKey.Header.tpub, 18332), - REGTEST("regtest", 111, "mn", 196, "2", "bcrt", ExtendedKey.Header.tprv, ExtendedKey.Header.tpub, 18443); + REGTEST("regtest", 111, "mn", 196, "2", "bcrt", ExtendedKey.Header.tprv, ExtendedKey.Header.tpub, 18443), + SIGNET("signet", 111, "mn", 196, "2", "tb", ExtendedKey.Header.tprv, ExtendedKey.Header.tpub, 38332); Network(String name, int p2pkhAddressHeader, String p2pkhAddressPrefix, int p2shAddressHeader, String p2shAddressPrefix, String bech32AddressHrp, ExtendedKey.Header xprvHeader, ExtendedKey.Header xpubHeader, int defaultPort) { this.name = name; diff --git a/src/test/java/com/sparrowwallet/drongo/address/AddressTest.java b/src/test/java/com/sparrowwallet/drongo/address/AddressTest.java index ea93994..9978803 100644 --- a/src/test/java/com/sparrowwallet/drongo/address/AddressTest.java +++ b/src/test/java/com/sparrowwallet/drongo/address/AddressTest.java @@ -45,6 +45,10 @@ public class AddressTest { Address address9 = Address.fromString(Network.TESTNET, "2NCZUtUt6gzXyBiPEQi5yQyrgR6f6F6Ki6A"); Assert.assertTrue(address9 instanceof P2SHAddress); Assert.assertEquals("2NCZUtUt6gzXyBiPEQi5yQyrgR6f6F6Ki6A", address9.toString(Network.TESTNET)); + + Address address10 = Address.fromString(Network.SIGNET, "2NCZUtUt6gzXyBiPEQi5yQyrgR6f6F6Ki6A"); + Assert.assertTrue(address10 instanceof P2SHAddress); + Assert.assertEquals("2NCZUtUt6gzXyBiPEQi5yQyrgR6f6F6Ki6A", address10.toString(Network.SIGNET)); } @Test From faa8f71313ff102c9611f8a9265511029654a83c Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Mon, 1 Mar 2021 15:26:55 +0200 Subject: [PATCH 007/155] return boolean if labels have changed --- .../sparrowwallet/drongo/wallet/WalletNode.java | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/WalletNode.java b/src/main/java/com/sparrowwallet/drongo/wallet/WalletNode.java index 792d7f8..2854d83 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/WalletNode.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/WalletNode.java @@ -208,13 +208,16 @@ public class WalletNode implements Comparable { return copy; } - public void copyLabels(WalletNode pastNode) { + public boolean copyLabels(WalletNode pastNode) { if(pastNode == null) { - return; + return false; } + boolean changed = false; + if(label == null && pastNode.label != null) { label = pastNode.label; + changed = true; } for(BlockTransactionHashIndex txo : getTransactionOutputs()) { @@ -223,16 +226,22 @@ public class WalletNode implements Comparable { BlockTransactionHashIndex pastTxo = optPastTxo.get(); if(txo.getLabel() == null && pastTxo.getLabel() != null) { txo.setLabel(pastTxo.getLabel()); + changed = true; } if(txo.isSpent() && pastTxo.isSpent() && txo.getSpentBy().getLabel() == null && pastTxo.getSpentBy().getLabel() != null) { txo.getSpentBy().setLabel(pastTxo.getSpentBy().getLabel()); + changed = true; } } } for(WalletNode childNode : getChildren()) { Optional optPastChildNode = pastNode.getChildren().stream().filter(node -> node.equals(childNode)).findFirst(); - optPastChildNode.ifPresent(childNode::copyLabels); + if(optPastChildNode.isPresent()) { + changed |= childNode.copyLabels(optPastChildNode.get()); + } } + + return changed; } } From b84aa2e7cb0c1f78fb36d610295ade0439e0df2a Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Mon, 1 Mar 2021 16:30:12 +0200 Subject: [PATCH 008/155] set log level dynamically --- src/main/java/com/sparrowwallet/drongo/Drongo.java | 6 ++++++ src/main/java/module-info.java | 1 + 2 files changed, 7 insertions(+) diff --git a/src/main/java/com/sparrowwallet/drongo/Drongo.java b/src/main/java/com/sparrowwallet/drongo/Drongo.java index 5f60c70..6d77694 100644 --- a/src/main/java/com/sparrowwallet/drongo/Drongo.java +++ b/src/main/java/com/sparrowwallet/drongo/Drongo.java @@ -3,6 +3,7 @@ package com.sparrowwallet.drongo; import com.sparrowwallet.drongo.rpc.BitcoinJSONRPCClient; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.slf4j.event.Level; import org.zeromq.SocketType; import org.zeromq.ZContext; import org.zeromq.ZMQ; @@ -74,4 +75,9 @@ public class Drongo { public List getWallets() { return watchWallets; } + + public static void setRootLogLevel(Level level) { + ch.qos.logback.classic.Logger root = (ch.qos.logback.classic.Logger)LoggerFactory.getLogger(org.slf4j.Logger.ROOT_LOGGER_NAME); + root.setLevel(ch.qos.logback.classic.Level.toLevel(level.toString())); + } } diff --git a/src/main/java/module-info.java b/src/main/java/module-info.java index fbd2c9f..af29d6a 100644 --- a/src/main/java/module-info.java +++ b/src/main/java/module-info.java @@ -3,6 +3,7 @@ open module com.sparrowwallet.drongo { requires de.mkammerer.argon2; requires slf4j.api; requires logback.core; + requires logback.classic; requires json.simple; requires jeromq; exports com.sparrowwallet.drongo; From c084a0de7e92bbc500234e66dcec690475ac9121 Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Thu, 4 Mar 2021 12:59:49 +0200 Subject: [PATCH 009/155] dont allow negative values to enter tx when send max true --- src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java index e17f7c7..d772166 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java @@ -497,11 +497,15 @@ public class Wallet { //If sending all selected utxos, set the recipient amount to equal to total of those utxos less the no change fee long maxSendAmt = totalSelectedAmt - noChangeFeeRequiredAmt; + if(maxSendAmt < 0) { + throw new InsufficientFundsException("Not enough combined value in selected UTXOs for fee of " + noChangeFeeRequiredAmt); + } + Optional optMaxPayment = payments.stream().filter(payment -> payment.isSendMax()).findFirst(); if(optMaxPayment.isPresent()) { Payment maxPayment = optMaxPayment.get(); maxSendAmt = maxSendAmt - payments.stream().filter(payment -> !maxPayment.equals(payment)).map(Payment::getAmount).mapToLong(v -> v).sum(); - if(maxPayment.getAmount() != maxSendAmt) { + if(maxSendAmt > 0 && maxPayment.getAmount() != maxSendAmt) { maxPayment.setAmount(maxSendAmt); totalPaymentAmount = payments.stream().map(Payment::getAmount).mapToLong(v -> v).sum(); continue; From 5b2e21b3d7cc5d6dff730baeec5efbb419f3555c Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Mon, 8 Mar 2021 09:16:28 +0200 Subject: [PATCH 010/155] provide framework for application logging --- .../drongo/ApplicationAppender.java | 20 +++++++++++++++++++ .../com/sparrowwallet/drongo/LogHandler.java | 7 +++++++ 2 files changed, 27 insertions(+) create mode 100644 src/main/java/com/sparrowwallet/drongo/ApplicationAppender.java create mode 100644 src/main/java/com/sparrowwallet/drongo/LogHandler.java diff --git a/src/main/java/com/sparrowwallet/drongo/ApplicationAppender.java b/src/main/java/com/sparrowwallet/drongo/ApplicationAppender.java new file mode 100644 index 0000000..18d0f74 --- /dev/null +++ b/src/main/java/com/sparrowwallet/drongo/ApplicationAppender.java @@ -0,0 +1,20 @@ +package com.sparrowwallet.drongo; + +import ch.qos.logback.classic.spi.ILoggingEvent; +import ch.qos.logback.core.AppenderBase; +import org.slf4j.event.Level; + +import java.lang.reflect.InvocationTargetException; + +public class ApplicationAppender extends AppenderBase { + private LogHandler callback; + + @Override + protected void append(ILoggingEvent e) { + callback.handleLog(e.getThreadName(), Level.valueOf(e.getLevel().toString()), e.getMessage(), e.getLoggerName(), e.getTimeStamp(), e.getCallerData()); + } + + public void setCallback(String callback) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException { + this.callback = (LogHandler)Class.forName(callback).getConstructor().newInstance(); + } +} diff --git a/src/main/java/com/sparrowwallet/drongo/LogHandler.java b/src/main/java/com/sparrowwallet/drongo/LogHandler.java new file mode 100644 index 0000000..778e882 --- /dev/null +++ b/src/main/java/com/sparrowwallet/drongo/LogHandler.java @@ -0,0 +1,7 @@ +package com.sparrowwallet.drongo; + +import org.slf4j.event.Level; + +public interface LogHandler { + void handleLog(String threadName, Level level, String message, String loggerName, long timestamp, StackTraceElement[] callerData); +} From 533791edcf38a6ca05857483df15a5c54a4554f0 Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Mon, 8 Mar 2021 16:20:35 +0200 Subject: [PATCH 011/155] use fractional tx virtual size --- .../java/com/sparrowwallet/drongo/protocol/Transaction.java | 4 ++-- src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/sparrowwallet/drongo/protocol/Transaction.java b/src/main/java/com/sparrowwallet/drongo/protocol/Transaction.java index e7c7f22..46425a3 100644 --- a/src/main/java/com/sparrowwallet/drongo/protocol/Transaction.java +++ b/src/main/java/com/sparrowwallet/drongo/protocol/Transaction.java @@ -303,8 +303,8 @@ public class Transaction extends ChildMessage { return length; } - public int getVirtualSize() { - return (int)Math.ceil((double)getWeightUnits() / (double)WITNESS_SCALE_FACTOR); + public double getVirtualSize() { + return (double)getWeightUnits() / (double)WITNESS_SCALE_FACTOR; } public int getWeightUnits() { diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java index d772166..17f3d06 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java @@ -489,7 +489,7 @@ public class Wallet { transaction.addOutput(payment.getAmount(), payment.getAddress()); } - int noChangeVSize = transaction.getVirtualSize(); + double noChangeVSize = transaction.getVirtualSize(); long noChangeFeeRequiredAmt = (fee == null ? (long)(feeRate * noChangeVSize) : fee); //Add 1 satoshi to accommodate longer signatures when feeRate equals default min relay fee to ensure fee is sufficient @@ -528,7 +528,7 @@ public class Wallet { //Change output is required, determine new fee once change output has been added WalletNode changeNode = getFreshNode(KeyPurpose.CHANGE); TransactionOutput changeOutput = new TransactionOutput(transaction, changeAmt, getOutputScript(changeNode)); - int changeVSize = noChangeVSize + changeOutput.getLength(); + double changeVSize = noChangeVSize + changeOutput.getLength(); long changeFeeRequiredAmt = (fee == null ? (long)(feeRate * changeVSize) : fee); changeFeeRequiredAmt = (feeRate == Transaction.DEFAULT_MIN_RELAY_FEE ? changeFeeRequiredAmt + 1 : changeFeeRequiredAmt); From e974c3f4223d1771aa59013c31311cf3d85e0915 Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Wed, 10 Mar 2021 11:28:59 +0200 Subject: [PATCH 012/155] sort descriptor xpubs lexicographically when child derivation paths are supplied --- .../drongo/OutputDescriptor.java | 33 +++++++++++++++---- 1 file changed, 27 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/sparrowwallet/drongo/OutputDescriptor.java b/src/main/java/com/sparrowwallet/drongo/OutputDescriptor.java index e9bbbe6..0e8bfd9 100644 --- a/src/main/java/com/sparrowwallet/drongo/OutputDescriptor.java +++ b/src/main/java/com/sparrowwallet/drongo/OutputDescriptor.java @@ -9,10 +9,7 @@ import com.sparrowwallet.drongo.policy.PolicyType; import com.sparrowwallet.drongo.protocol.ProtocolException; import com.sparrowwallet.drongo.protocol.Script; import com.sparrowwallet.drongo.protocol.ScriptType; -import com.sparrowwallet.drongo.wallet.Keystore; -import com.sparrowwallet.drongo.wallet.KeystoreSource; -import com.sparrowwallet.drongo.wallet.Wallet; -import com.sparrowwallet.drongo.wallet.WalletModel; +import com.sparrowwallet.drongo.wallet.*; import java.math.BigInteger; import java.util.*; @@ -257,12 +254,16 @@ public class OutputDescriptor { } public static OutputDescriptor getOutputDescriptor(Wallet wallet, KeyPurpose keyPurpose) { + return getOutputDescriptor(wallet, keyPurpose, null); + } + + public static OutputDescriptor getOutputDescriptor(Wallet wallet, KeyPurpose keyPurpose, Integer index) { Map extendedKeyDerivationMap = new LinkedHashMap<>(); Map extendedKeyChildDerivationMap = new LinkedHashMap<>(); for(Keystore keystore : wallet.getKeystores()) { extendedKeyDerivationMap.put(keystore.getExtendedPublicKey(), keystore.getKeyDerivation()); if(keyPurpose != null) { - extendedKeyChildDerivationMap.put(keystore.getExtendedPublicKey(), keyPurpose.getPathIndex().num() + "/*"); + extendedKeyChildDerivationMap.put(keystore.getExtendedPublicKey(), keyPurpose.getPathIndex().num() + "/" + (index == null ? "*" : index)); } } @@ -431,7 +432,7 @@ public class OutputDescriptor { builder.append(ScriptType.MULTISIG.getDescriptor()); StringJoiner joiner = new StringJoiner(","); joiner.add(Integer.toString(multisigThreshold)); - for(ExtendedKey pubKey : extendedPublicKeys.keySet()) { + for(ExtendedKey pubKey : sortExtendedPubKeys(extendedPublicKeys.keySet())) { String extKeyString = toString(pubKey, addKeyOrigin); joiner.add(extKeyString); } @@ -452,6 +453,26 @@ public class OutputDescriptor { return builder.toString(); } + private List sortExtendedPubKeys(Collection keys) { + List sortedKeys = new ArrayList<>(keys); + if(mapChildrenDerivations == null || mapChildrenDerivations.isEmpty()) { + return sortedKeys; + } + + Utils.LexicographicByteArrayComparator lexicographicByteArrayComparator = new Utils.LexicographicByteArrayComparator(); + sortedKeys.sort((o1, o2) -> { + List derivation1 = KeyDerivation.parsePath(mapChildrenDerivations.get(o1)); + derivation1.add(0, o1.getKeyChildNumber()); + ECKey key1 = o1.getKey(derivation1); + List derivation2 = KeyDerivation.parsePath(mapChildrenDerivations.get(o2)); + derivation2.add(0, o2.getKeyChildNumber()); + ECKey key2 = o2.getKey(derivation2); + return lexicographicByteArrayComparator.compare(key1.getPubKey(), key2.getPubKey()); + }); + + return sortedKeys; + } + private String toString(ExtendedKey pubKey, boolean addKeyOrigin) { StringBuilder keyBuilder = new StringBuilder(); KeyDerivation keyDerivation = extendedPublicKeys.get(pubKey); From 49654b7c82d104f7898eff95f0ac3cec96fbc0ec Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Thu, 1 Apr 2021 09:51:43 +0200 Subject: [PATCH 013/155] ensure safe psbt testing --- .../java/com/sparrowwallet/drongo/psbt/PSBT.java | 14 ++++++++++---- .../com/sparrowwallet/drongo/psbt/PSBTTest.java | 8 ++++++++ 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/sparrowwallet/drongo/psbt/PSBT.java b/src/main/java/com/sparrowwallet/drongo/psbt/PSBT.java index 32d6c47..125e8a2 100644 --- a/src/main/java/com/sparrowwallet/drongo/psbt/PSBT.java +++ b/src/main/java/com/sparrowwallet/drongo/psbt/PSBT.java @@ -600,11 +600,17 @@ public class PSBT { } public static boolean isPSBT(String s) { - if (Utils.isHex(s) && s.startsWith(PSBT_MAGIC_HEX)) { - return true; - } else { - return Utils.isBase64(s) && Utils.bytesToHex(Base64.decode(s)).startsWith(PSBT_MAGIC_HEX); + try { + if(Utils.isHex(s) && s.startsWith(PSBT_MAGIC_HEX)) { + return true; + } else { + return Utils.isBase64(s) && Utils.bytesToHex(Base64.decode(s)).startsWith(PSBT_MAGIC_HEX); + } + } catch(Exception e) { + //ignore } + + return false; } public static PSBT fromString(String strPSBT) throws PSBTParseException { diff --git a/src/test/java/com/sparrowwallet/drongo/psbt/PSBTTest.java b/src/test/java/com/sparrowwallet/drongo/psbt/PSBTTest.java index bb77ecc..1d41e8b 100644 --- a/src/test/java/com/sparrowwallet/drongo/psbt/PSBTTest.java +++ b/src/test/java/com/sparrowwallet/drongo/psbt/PSBTTest.java @@ -376,6 +376,14 @@ public class PSBTTest { Assert.assertEquals("0200000000010258e87a21b56daf0c23be8e7070456c336f7cbaa5c8757924f545887bb2abdd7500000000da00473044022074018ad4180097b873323c0015720b3684cc8123891048e7dbcd9b55ad679c99022073d369b740e3eb53dcefa33823c8070514ca55a7dd9544f157c167913261118c01483045022100f61038b308dc1da865a34852746f015772934208c6d24454393cd99bdf2217770220056e675a675a6d0a02b85b14e5e29074d8a25a9b5760bea2816f661910a006ea01475221029583bf39ae0a609747ad199addd634fa6108559d6c5cd39b4c2183f1ab96e07f2102dab61ff49a14db6a7d02b0cd1fbb78fc4b18312b5b4e54dae4dba2fbfef536d752aeffffffff838d0427d0ec650a68aa46bb0b098aea4422c071b2ca78352a077959d07cea1d01000000232200208c2353173743b595dfb4a07b72ba8e42e3797da74e87fe7d9d7497e3b2028903ffffffff0270aaf00800000000160014d85c2b71d0060b09c9886aeb815e50991dda124d00e1f5050000000016001400aea9a2e5f0f876a588df5546e8742d1d87008f000400473044022062eb7a556107a7c73f45ac4ab5a1dddf6f7075fb1275969a7f383efff784bcb202200c05dbb7470dbf2f08557dd356c7325c1ed30913e996cd3840945db12228da5f01473044022065f45ba5998b59a27ffe1a7bed016af1f1f90d54b3aa8f7450aa5f56a25103bd02207f724703ad1edb96680b284b56d4ffcb88f7fb759eabbe08aa30f29b851383d20147522103089dc10c7ac6db54f91329af617333db388cead0c231f723379d1b99030b02dc21023add904f3d6dcf59ddb906b0dee23529b7ffb9ed50e5e86151926860221f0e7352ae00000000", Utils.bytesToHex(transaction.bitcoinSerialize())); } + @Test + public void isPSBT() { + String s = null; + Assert.assertFalse(PSBT.isPSBT(s)); + Assert.assertFalse(PSBT.isPSBT("")); + Assert.assertFalse(PSBT.isPSBT("x")); + } + @After public void tearDown() throws Exception { Network.set(null); From 428054d375b638bb7e08133fdffe6f1dd438cca9 Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Mon, 12 Apr 2021 09:33:52 +0200 Subject: [PATCH 014/155] fix p2sh-p2wpkh description --- src/main/java/com/sparrowwallet/drongo/protocol/ScriptType.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/sparrowwallet/drongo/protocol/ScriptType.java b/src/main/java/com/sparrowwallet/drongo/protocol/ScriptType.java index d74d50e..2a0a7c0 100644 --- a/src/main/java/com/sparrowwallet/drongo/protocol/ScriptType.java +++ b/src/main/java/com/sparrowwallet/drongo/protocol/ScriptType.java @@ -555,7 +555,7 @@ public enum ScriptType { return List.of(MULTI); } }, - P2SH_P2WPKH("P2SH-P2WPKH", "Nested Segwit (P2SH-P2WSH)", "m/49'/0'/0'") { + P2SH_P2WPKH("P2SH-P2WPKH", "Nested Segwit (P2SH-P2WPKH)", "m/49'/0'/0'") { @Override public Address getAddress(byte[] scriptHash) { return P2SH.getAddress(scriptHash); From b7038b19f9d44cfc50af151927b06f9aada9d5e7 Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Mon, 12 Apr 2021 13:42:11 +0200 Subject: [PATCH 015/155] add option to strip sensitive info from psbt serialization --- build.gradle | 4 ++-- .../com/sparrowwallet/drongo/psbt/PSBT.java | 24 +++++++++++++++---- 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/build.gradle b/build.gradle index 7f0eaa3..ae5cca6 100644 --- a/build.gradle +++ b/build.gradle @@ -31,8 +31,8 @@ tasks.withType(AbstractArchiveTask) { group 'com.sparrowwallet' version '0.9' -sourceCompatibility = 1.9 -targetCompatibility = 1.9 +sourceCompatibility = 11 +targetCompatibility = 11 repositories { mavenCentral() diff --git a/src/main/java/com/sparrowwallet/drongo/psbt/PSBT.java b/src/main/java/com/sparrowwallet/drongo/psbt/PSBT.java index 125e8a2..14f3086 100644 --- a/src/main/java/com/sparrowwallet/drongo/psbt/PSBT.java +++ b/src/main/java/com/sparrowwallet/drongo/psbt/PSBT.java @@ -16,6 +16,8 @@ import java.nio.ByteBuffer; import java.util.*; import static com.sparrowwallet.drongo.psbt.PSBTEntry.*; +import static com.sparrowwallet.drongo.psbt.PSBTInput.PSBT_IN_BIP32_DERIVATION; +import static com.sparrowwallet.drongo.psbt.PSBTOutput.*; public class PSBT { public static final byte PSBT_GLOBAL_UNSIGNED_TX = 0x00; @@ -432,6 +434,10 @@ public class PSBT { } public byte[] serialize() { + return serialize(true); + } + + public byte[] serialize(boolean includeXpubs) { ByteArrayOutputStream baos = new ByteArrayOutputStream(); baos.writeBytes(Utils.hexToBytes(PSBT_MAGIC_HEX)); @@ -439,14 +445,18 @@ public class PSBT { List globalEntries = getGlobalEntries(); for(PSBTEntry entry : globalEntries) { - entry.serializeToStream(baos); + if(includeXpubs || (entry.getKeyType() != PSBT_GLOBAL_BIP32_PUBKEY && entry.getKeyType() != PSBT_GLOBAL_PROPRIETARY)) { + entry.serializeToStream(baos); + } } baos.writeBytes(new byte[] {(byte)0x00}); for(PSBTInput psbtInput : getPsbtInputs()) { List inputEntries = psbtInput.getInputEntries(); for(PSBTEntry entry : inputEntries) { - entry.serializeToStream(baos); + if(includeXpubs || entry.getKeyType() != PSBT_IN_BIP32_DERIVATION) { + entry.serializeToStream(baos); + } } baos.writeBytes(new byte[] {(byte)0x00}); } @@ -454,7 +464,9 @@ public class PSBT { for(PSBTOutput psbtOutput : getPsbtOutputs()) { List outputEntries = psbtOutput.getOutputEntries(); for(PSBTEntry entry : outputEntries) { - entry.serializeToStream(baos); + if(includeXpubs || (entry.getKeyType() != PSBT_OUT_REDEEM_SCRIPT && entry.getKeyType() != PSBT_OUT_WITNESS_SCRIPT && entry.getKeyType() != PSBT_OUT_BIP32_DERIVATION && entry.getKeyType() != PSBT_OUT_PROPRIETARY)) { + entry.serializeToStream(baos); + } } baos.writeBytes(new byte[] {(byte)0x00}); } @@ -584,7 +596,11 @@ public class PSBT { } public String toBase64String() { - return Base64.toBase64String(serialize()); + return toBase64String(true); + } + + public String toBase64String(boolean includeXpubs) { + return Base64.toBase64String(serialize(includeXpubs)); } public static boolean isPSBT(byte[] b) { From a56f8971c022192dbce0dfc5da3c417b605e4b4f Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Mon, 12 Apr 2021 15:46:44 +0200 Subject: [PATCH 016/155] support blockchain ordering of txes a separate method --- .../sparrowwallet/drongo/wallet/BlockTransaction.java | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/BlockTransaction.java b/src/main/java/com/sparrowwallet/drongo/wallet/BlockTransaction.java index 5f0705a..ea2d122 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/BlockTransaction.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/BlockTransaction.java @@ -37,6 +37,15 @@ public class BlockTransaction extends BlockTransactionHash implements Comparable @Override public int compareTo(BlockTransaction blkTx) { + int blockOrder = compareBlockOrder(blkTx); + if(blockOrder != 0) { + return blockOrder; + } + + return super.compareTo(blkTx); + } + + public int compareBlockOrder(BlockTransaction blkTx) { if(getHeight() != blkTx.getHeight()) { return getComparisonHeight() - blkTx.getComparisonHeight(); } @@ -49,7 +58,7 @@ public class BlockTransaction extends BlockTransactionHash implements Comparable return -1; } - return super.compareTo(blkTx); + return 0; } private static List getReferencedOutpoints(BlockTransaction blockchainTransaction) { From 891499aff04b69f53bf143464001b96b44a0ec53 Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Fri, 16 Apr 2021 12:30:22 +0200 Subject: [PATCH 017/155] safer istransaction test --- .../java/com/sparrowwallet/drongo/protocol/Transaction.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/java/com/sparrowwallet/drongo/protocol/Transaction.java b/src/main/java/com/sparrowwallet/drongo/protocol/Transaction.java index 46425a3..a3c2ab5 100644 --- a/src/main/java/com/sparrowwallet/drongo/protocol/Transaction.java +++ b/src/main/java/com/sparrowwallet/drongo/protocol/Transaction.java @@ -437,6 +437,9 @@ public class Transaction extends ChildMessage { public static boolean isTransaction(byte[] bytes) { //Incomplete quick test + if(bytes.length == 0) { + return false; + } long version = Utils.readUint32(bytes, 0); return version > 0 && version < 5; } From 1aeaacaf59484c76d5bf485dabb4a632c5230032 Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Mon, 19 Apr 2021 08:56:05 +0200 Subject: [PATCH 018/155] preserve capitalization in keystore naming in policy script --- src/main/java/com/sparrowwallet/drongo/wallet/Keystore.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/Keystore.java b/src/main/java/com/sparrowwallet/drongo/wallet/Keystore.java index 1334367..d7d6e01 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/Keystore.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/Keystore.java @@ -32,7 +32,7 @@ public class Keystore { } public String getScriptName() { - return label.replace(" ", "").toLowerCase(); + return label.replace(" ", ""); } public void setLabel(String label) { From 85e8b97a8c8d21bfbb76096285eec95d28384090 Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Tue, 20 Apr 2021 08:27:26 +0200 Subject: [PATCH 019/155] support extended master private key keystores --- .../sparrowwallet/drongo/wallet/Keystore.java | 83 ++++++++--- .../wallet/MasterPrivateExtendedKey.java | 134 ++++++++++++++++++ .../sparrowwallet/drongo/wallet/Wallet.java | 6 +- .../drongo/wallet/PolicyTest.java | 12 +- 4 files changed, 210 insertions(+), 25 deletions(-) create mode 100644 src/main/java/com/sparrowwallet/drongo/wallet/MasterPrivateExtendedKey.java diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/Keystore.java b/src/main/java/com/sparrowwallet/drongo/wallet/Keystore.java index d7d6e01..e8d2614 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/Keystore.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/Keystore.java @@ -17,6 +17,7 @@ public class Keystore { private WalletModel walletModel = WalletModel.SPARROW; private KeyDerivation keyDerivation; private ExtendedKey extendedPublicKey; + private MasterPrivateExtendedKey masterPrivateExtendedKey; private DeterministicSeed seed; public Keystore() { @@ -71,6 +72,22 @@ public class Keystore { this.extendedPublicKey = extendedPublicKey; } + public boolean hasMasterPrivateExtendedKey() { + return masterPrivateExtendedKey != null; + } + + public MasterPrivateExtendedKey getMasterPrivateExtendedKey() { + return masterPrivateExtendedKey; + } + + public void setMasterPrivateExtendedKey(MasterPrivateExtendedKey masterPrivateExtendedKey) { + this.masterPrivateExtendedKey = masterPrivateExtendedKey; + } + + public boolean hasSeed() { + return seed != null; + } + public DeterministicSeed getSeed() { return seed; } @@ -79,16 +96,28 @@ public class Keystore { this.seed = seed; } + public boolean hasPrivateKey() { + return hasSeed() || hasMasterPrivateExtendedKey(); + } + public DeterministicKey getMasterPrivateKey() throws MnemonicException { - if(seed == null) { - throw new IllegalArgumentException("Keystore does not contain a seed"); + if(seed == null && masterPrivateExtendedKey == null) { + throw new IllegalArgumentException("Keystore does not contain a master private key, or seed to derive one from"); } - if(seed.isEncrypted()) { - throw new IllegalArgumentException("Seed is encrypted"); + if(seed != null) { + if(seed.isEncrypted()) { + throw new IllegalArgumentException("Seed is encrypted"); + } + + return HDKeyDerivation.createMasterPrivateKey(seed.getSeedBytes()); } - return HDKeyDerivation.createMasterPrivateKey(seed.getSeedBytes()); + if(masterPrivateExtendedKey.isEncrypted()) { + throw new IllegalArgumentException("Master private key is encrypted"); + } + + return masterPrivateExtendedKey.getPrivateKey(); } public ExtendedKey getExtendedMasterPrivateKey() throws MnemonicException { @@ -178,11 +207,11 @@ public class Keystore { } if(source == KeystoreSource.SW_SEED) { - if(seed == null) { - throw new InvalidKeystoreException("Source of " + source + " but no seed is present"); + if(seed == null && masterPrivateExtendedKey == null) { + throw new InvalidKeystoreException("Source of " + source + " but no seed or master private key is present"); } - if(!seed.isEncrypted()) { + if((seed != null && !seed.isEncrypted()) || (masterPrivateExtendedKey != null && !masterPrivateExtendedKey.isEncrypted())) { try { List derivation = getKeyDerivation().getDerivation(); DeterministicKey derivedKey = getExtendedMasterPrivateKey().getKey(derivation); @@ -208,6 +237,9 @@ public class Keystore { if(extendedPublicKey != null) { copy.setExtendedPublicKey(extendedPublicKey.copy()); } + if(masterPrivateExtendedKey != null) { + copy.setMasterPrivateExtendedKey(masterPrivateExtendedKey.copy()); + } if(seed != null) { copy.setSeed(seed.copy()); } @@ -217,50 +249,69 @@ public class Keystore { public static Keystore fromSeed(DeterministicSeed seed, List derivation) throws MnemonicException { Keystore keystore = new Keystore(); keystore.setSeed(seed); + keystore.setLabel(seed.getType().name()); + rederiveKeystoreFromMaster(keystore, derivation); + return keystore; + } + + public static Keystore fromMasterPrivateExtendedKey(MasterPrivateExtendedKey masterPrivateExtendedKey, List derivation) throws MnemonicException { + Keystore keystore = new Keystore(); + keystore.setMasterPrivateExtendedKey(masterPrivateExtendedKey); + keystore.setLabel("Master Key"); + rederiveKeystoreFromMaster(keystore, derivation); + return keystore; + } + + private static void rederiveKeystoreFromMaster(Keystore keystore, List derivation) throws MnemonicException { ExtendedKey xprv = keystore.getExtendedMasterPrivateKey(); String masterFingerprint = Utils.bytesToHex(xprv.getKey().getFingerprint()); DeterministicKey derivedKey = xprv.getKey(derivation); DeterministicKey derivedKeyPublicOnly = derivedKey.dropPrivateBytes().dropParent(); ExtendedKey xpub = new ExtendedKey(derivedKeyPublicOnly, derivedKey.getParentFingerprint(), derivation.isEmpty() ? ChildNumber.ZERO : derivation.get(derivation.size() - 1)); - keystore.setLabel(seed.getType().name()); keystore.setSource(KeystoreSource.SW_SEED); keystore.setWalletModel(WalletModel.SPARROW); keystore.setKeyDerivation(new KeyDerivation(masterFingerprint, KeyDerivation.writePath(derivation))); keystore.setExtendedPublicKey(ExtendedKey.fromDescriptor(xpub.toString())); - - return keystore; - } - - public boolean hasSeed() { - return seed != null; } public boolean isEncrypted() { - return seed != null && seed.isEncrypted(); + return (seed != null && seed.isEncrypted()) || (masterPrivateExtendedKey != null && masterPrivateExtendedKey.isEncrypted()); } public void encrypt(Key key) { if(hasSeed() && !seed.isEncrypted()) { seed = seed.encrypt(key); } + if(hasMasterPrivateExtendedKey() && !masterPrivateExtendedKey.isEncrypted()) { + masterPrivateExtendedKey = masterPrivateExtendedKey.encrypt(key); + } } public void decrypt(CharSequence password) { if(hasSeed() && seed.isEncrypted()) { seed = seed.decrypt(password); } + if(hasMasterPrivateExtendedKey() && masterPrivateExtendedKey.isEncrypted()) { + masterPrivateExtendedKey = masterPrivateExtendedKey.decrypt(password); + } } public void decrypt(Key key) { if(hasSeed() && seed.isEncrypted()) { seed = seed.decrypt(key); } + if(hasMasterPrivateExtendedKey() && masterPrivateExtendedKey.isEncrypted()) { + masterPrivateExtendedKey = masterPrivateExtendedKey.decrypt(key); + } } public void clearPrivate() { if(hasSeed()) { seed.clear(); } + if(hasMasterPrivateExtendedKey()) { + masterPrivateExtendedKey.clear(); + } } } diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/MasterPrivateExtendedKey.java b/src/main/java/com/sparrowwallet/drongo/wallet/MasterPrivateExtendedKey.java new file mode 100644 index 0000000..efd99b4 --- /dev/null +++ b/src/main/java/com/sparrowwallet/drongo/wallet/MasterPrivateExtendedKey.java @@ -0,0 +1,134 @@ +package com.sparrowwallet.drongo.wallet; + +import com.sparrowwallet.drongo.ExtendedKey; +import com.sparrowwallet.drongo.crypto.*; + +import java.nio.ByteBuffer; +import java.util.Arrays; + +public class MasterPrivateExtendedKey implements EncryptableItem { + private final byte[] privateKey; + private final byte[] chainCode; + + private final EncryptedData encryptedKey; + + public MasterPrivateExtendedKey(byte[] privateKey, byte[] chainCode) { + this.privateKey = privateKey; + this.chainCode = chainCode; + this.encryptedKey = null; + } + + public MasterPrivateExtendedKey(EncryptedData encryptedKey) { + this.privateKey = null; + this.chainCode = null; + this.encryptedKey = encryptedKey; + } + + public DeterministicKey getPrivateKey() { + return HDKeyDerivation.createMasterPrivKeyFromBytes(privateKey, chainCode); + } + + public ExtendedKey getExtendedPrivateKey() { + return new ExtendedKey(getPrivateKey(), new byte[4], ChildNumber.ZERO); + } + + @Override + public boolean isEncrypted() { + if((privateKey != null || chainCode != null) && encryptedKey != null) { + throw new IllegalStateException("Cannot be in a encrypted and unencrypted state"); + } + + return encryptedKey != null; + } + + @Override + public byte[] getSecretBytes() { + if(privateKey == null || chainCode == null) { + throw new IllegalStateException("Cannot get secret bytes for null or encrypted key"); + } + + ByteBuffer byteBuffer = ByteBuffer.allocate(64); + byteBuffer.put(privateKey); + byteBuffer.put(chainCode); + return byteBuffer.array(); + } + + @Override + public EncryptedData getEncryptedData() { + return encryptedKey; + } + + @Override + public EncryptionType getEncryptionType() { + return new EncryptionType(EncryptionType.Deriver.ARGON2, EncryptionType.Crypter.AES_CBC_PKCS7); + } + + @Override + public long getCreationTimeSeconds() { + return 0; + } + + public MasterPrivateExtendedKey encrypt(Key key) { + if(encryptedKey != null) { + throw new IllegalArgumentException("Trying to encrypt twice"); + } + if(privateKey == null || chainCode == null) { + throw new IllegalArgumentException("Private key data missing so cannot encrypt"); + } + + KeyCrypter keyCrypter = getEncryptionType().getCrypter().getKeyCrypter(); + byte[] secretBytes = getSecretBytes(); + EncryptedData encryptedKeyData = keyCrypter.encrypt(secretBytes, null, key); + Arrays.fill(secretBytes != null ? secretBytes : new byte[0], (byte)0); + + return new MasterPrivateExtendedKey(encryptedKeyData); + } + + public MasterPrivateExtendedKey decrypt(CharSequence password) { + if(!isEncrypted()) { + throw new IllegalStateException("Cannot decrypt unencrypted master private key"); + } + + KeyDeriver keyDeriver = getEncryptionType().getDeriver().getKeyDeriver(encryptedKey.getKeySalt()); + Key key = keyDeriver.deriveKey(password); + MasterPrivateExtendedKey seed = decrypt(key); + key.clear(); + + return seed; + } + + public MasterPrivateExtendedKey decrypt(Key key) { + if(!isEncrypted()) { + throw new IllegalStateException("Cannot decrypt unencrypted master private key"); + } + + KeyCrypter keyCrypter = getEncryptionType().getCrypter().getKeyCrypter(); + byte[] decrypted = keyCrypter.decrypt(encryptedKey, key); + try { + return new MasterPrivateExtendedKey(Arrays.copyOfRange(decrypted, 0, 32), Arrays.copyOfRange(decrypted, 32, 64)); + } finally { + Arrays.fill(decrypted, (byte)0); + } + } + + public MasterPrivateExtendedKey copy() { + if(isEncrypted()) { + return new MasterPrivateExtendedKey(encryptedKey.copy()); + } + + return new MasterPrivateExtendedKey(Arrays.copyOf(privateKey, 32), Arrays.copyOf(chainCode, 32)); + } + + public void clear() { + if(privateKey != null) { + Arrays.fill(privateKey, (byte)0); + } + if(chainCode != null) { + Arrays.fill(chainCode, (byte)0); + } + } + + public MasterPrivateExtendedKey fromXprv(ExtendedKey xprv) { + return new MasterPrivateExtendedKey(xprv.getKey().getPrivKeyBytes(), xprv.getKey().getChainCode()); + } +} diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java index 17f3d06..b5a3692 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java @@ -815,7 +815,7 @@ public class Wallet { public void sign(PSBT psbt) throws MnemonicException { Map signingNodes = getSigningNodes(psbt); for(Keystore keystore : getKeystores()) { - if(keystore.hasSeed()) { + if(keystore.hasPrivateKey()) { for(Map.Entry signingEntry : signingNodes.entrySet()) { ECKey privKey = keystore.getKey(signingEntry.getValue()); PSBTInput psbtInput = signingEntry.getKey(); @@ -1061,9 +1061,9 @@ public class Wallet { return copy; } - public boolean containsSeeds() { + public boolean containsPrivateKeys() { for(Keystore keystore : keystores) { - if(keystore.hasSeed()) { + if(keystore.hasPrivateKey()) { return true; } } diff --git a/src/test/java/com/sparrowwallet/drongo/wallet/PolicyTest.java b/src/test/java/com/sparrowwallet/drongo/wallet/PolicyTest.java index 0fe5c40..811579c 100644 --- a/src/test/java/com/sparrowwallet/drongo/wallet/PolicyTest.java +++ b/src/test/java/com/sparrowwallet/drongo/wallet/PolicyTest.java @@ -16,27 +16,27 @@ public class PolicyTest { Keystore keystore3 = new Keystore("Keystore 3"); Policy policy = Policy.getPolicy(PolicyType.SINGLE, ScriptType.P2PKH, List.of(keystore1), 1); - Assert.assertEquals("pkh(keystore1)", policy.getMiniscript().toString()); + Assert.assertEquals("pkh(keystore1)", policy.getMiniscript().toString().toLowerCase()); Assert.assertEquals(1, policy.getNumSignaturesRequired()); Policy policy2 = Policy.getPolicy(PolicyType.SINGLE, ScriptType.P2SH_P2WPKH, List.of(keystore1), 1); - Assert.assertEquals("sh(wpkh(keystore1))", policy2.getMiniscript().toString()); + Assert.assertEquals("sh(wpkh(keystore1))", policy2.getMiniscript().toString().toLowerCase()); Assert.assertEquals(1, policy2.getNumSignaturesRequired()); Policy policy3 = Policy.getPolicy(PolicyType.SINGLE, ScriptType.P2WPKH, List.of(keystore1), 1); - Assert.assertEquals("wpkh(keystore1)", policy3.getMiniscript().toString()); + Assert.assertEquals("wpkh(keystore1)", policy3.getMiniscript().toString().toLowerCase()); Assert.assertEquals(1, policy3.getNumSignaturesRequired()); Policy policy4 = Policy.getPolicy(PolicyType.MULTI, ScriptType.P2SH, List.of(keystore1, keystore2, keystore3), 2); - Assert.assertEquals("sh(sortedmulti(2,keystore1,keystore2,keystore3))", policy4.getMiniscript().toString()); + Assert.assertEquals("sh(sortedmulti(2,keystore1,keystore2,keystore3))", policy4.getMiniscript().toString().toLowerCase()); Assert.assertEquals(2, policy4.getNumSignaturesRequired()); Policy policy5 = Policy.getPolicy(PolicyType.MULTI, ScriptType.P2SH_P2WSH, List.of(keystore1, keystore2, keystore3), 2); - Assert.assertEquals("sh(wsh(sortedmulti(2,keystore1,keystore2,keystore3)))", policy5.getMiniscript().toString()); + Assert.assertEquals("sh(wsh(sortedmulti(2,keystore1,keystore2,keystore3)))", policy5.getMiniscript().toString().toLowerCase()); Assert.assertEquals(2, policy5.getNumSignaturesRequired()); Policy policy6 = Policy.getPolicy(PolicyType.MULTI, ScriptType.P2WSH, List.of(keystore1, keystore2, keystore3), 2); - Assert.assertEquals("wsh(sortedmulti(2,keystore1,keystore2,keystore3))", policy6.getMiniscript().toString()); + Assert.assertEquals("wsh(sortedmulti(2,keystore1,keystore2,keystore3))", policy6.getMiniscript().toString().toLowerCase()); Assert.assertEquals(2, policy6.getNumSignaturesRequired()); } } From a25dfa5c7671023b60d1773cf603b4d46885a546 Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Tue, 20 Apr 2021 11:08:13 +0200 Subject: [PATCH 020/155] allow external unconfirmed utxos to be spent --- src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java index b5a3692..886bcff 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java @@ -574,7 +574,7 @@ public class Wallet { filters.add(new OutputGroup.Filter(1, 6)); filters.add(new OutputGroup.Filter(1, 1)); if(includeMempoolChange) { - filters.add(new OutputGroup.Filter(0, 1)); + filters.add(new OutputGroup.Filter(0, 0)); } for(OutputGroup.Filter filter : filters) { From efaa6a066d2b7d7f982086060aa8f014ca89a190 Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Wed, 21 Apr 2021 09:37:01 +0200 Subject: [PATCH 021/155] improve variable naming for utxo selection criteria --- .../sparrowwallet/drongo/wallet/Wallet.java | 32 +++++++++---------- .../drongo/wallet/WalletNode.java | 4 +-- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java index 886bcff..a9911d0 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java @@ -336,16 +336,16 @@ public class Wallet { return getWalletUtxos(false); } - public Map getWalletUtxos(boolean includeMempoolInputs) { + public Map getWalletUtxos(boolean includeSpentMempoolOutputs) { Map walletUtxos = new TreeMap<>(); - getWalletUtxos(walletUtxos, getNode(KeyPurpose.RECEIVE), includeMempoolInputs); - getWalletUtxos(walletUtxos, getNode(KeyPurpose.CHANGE), includeMempoolInputs); + getWalletUtxos(walletUtxos, getNode(KeyPurpose.RECEIVE), includeSpentMempoolOutputs); + getWalletUtxos(walletUtxos, getNode(KeyPurpose.CHANGE), includeSpentMempoolOutputs); return walletUtxos; } - private void getWalletUtxos(Map walletUtxos, WalletNode purposeNode, boolean includeMempoolInputs) { + private void getWalletUtxos(Map walletUtxos, WalletNode purposeNode, boolean includeSpentMempoolOutputs) { for(WalletNode addressNode : purposeNode.getChildren()) { - for(BlockTransactionHashIndex utxo : addressNode.getUnspentTransactionOutputs(includeMempoolInputs)) { + for(BlockTransactionHashIndex utxo : addressNode.getUnspentTransactionOutputs(includeSpentMempoolOutputs)) { walletUtxos.put(utxo, addressNode); } } @@ -460,12 +460,12 @@ public class Wallet { return getFee(changeOutput, feeRate, longTermFeeRate); } - public WalletTransaction createWalletTransaction(List utxoSelectors, List utxoFilters, List payments, double feeRate, double longTermFeeRate, Long fee, Integer currentBlockHeight, boolean groupByAddress, boolean includeMempoolChange, boolean includeMempoolInputs) throws InsufficientFundsException { + public WalletTransaction createWalletTransaction(List utxoSelectors, List utxoFilters, List payments, double feeRate, double longTermFeeRate, Long fee, Integer currentBlockHeight, boolean groupByAddress, boolean includeMempoolOutputs, boolean includeSpentMempoolOutputs) throws InsufficientFundsException { long totalPaymentAmount = payments.stream().map(Payment::getAmount).mapToLong(v -> v).sum(); long valueRequiredAmt = totalPaymentAmount; while(true) { - Map selectedUtxos = selectInputs(utxoSelectors, utxoFilters, valueRequiredAmt, feeRate, longTermFeeRate, groupByAddress, includeMempoolChange, includeMempoolInputs); + Map selectedUtxos = selectInputs(utxoSelectors, utxoFilters, valueRequiredAmt, feeRate, longTermFeeRate, groupByAddress, includeMempoolOutputs, includeSpentMempoolOutputs); long totalSelectedAmt = selectedUtxos.keySet().stream().mapToLong(BlockTransactionHashIndex::getValue).sum(); Transaction transaction = new Transaction(); @@ -567,13 +567,13 @@ public class Wallet { } } - private Map selectInputs(List utxoSelectors, List utxoFilters, Long targetValue, double feeRate, double longTermFeeRate, boolean groupByAddress, boolean includeMempoolChange, boolean includeMempoolInputs) throws InsufficientFundsException { - List utxoPool = getGroupedUtxos(utxoFilters, feeRate, longTermFeeRate, groupByAddress, includeMempoolInputs); + private Map selectInputs(List utxoSelectors, List utxoFilters, Long targetValue, double feeRate, double longTermFeeRate, boolean groupByAddress, boolean includeMempoolOutputs, boolean includeSpentMempoolOutputs) throws InsufficientFundsException { + List utxoPool = getGroupedUtxos(utxoFilters, feeRate, longTermFeeRate, groupByAddress, includeSpentMempoolOutputs); List filters = new ArrayList<>(); filters.add(new OutputGroup.Filter(1, 6)); filters.add(new OutputGroup.Filter(1, 1)); - if(includeMempoolChange) { + if(includeMempoolOutputs) { filters.add(new OutputGroup.Filter(0, 0)); } @@ -584,7 +584,7 @@ public class Wallet { Collection selectedInputs = utxoSelector.select(targetValue, filteredPool); long total = selectedInputs.stream().mapToLong(BlockTransactionHashIndex::getValue).sum(); if(total > targetValue) { - Map utxos = getWalletUtxos(includeMempoolInputs); + Map utxos = getWalletUtxos(includeSpentMempoolOutputs); utxos.keySet().retainAll(selectedInputs); return utxos; } @@ -594,17 +594,17 @@ public class Wallet { throw new InsufficientFundsException("Not enough combined value in UTXOs for output value " + targetValue); } - private List getGroupedUtxos(List utxoFilters, double feeRate, double longTermFeeRate, boolean groupByAddress, boolean includeMempoolInputs) { + private List getGroupedUtxos(List utxoFilters, double feeRate, double longTermFeeRate, boolean groupByAddress, boolean includeSpentMempoolOutputs) { List outputGroups = new ArrayList<>(); - getGroupedUtxos(outputGroups, getNode(KeyPurpose.RECEIVE), utxoFilters, feeRate, longTermFeeRate, groupByAddress, includeMempoolInputs); - getGroupedUtxos(outputGroups, getNode(KeyPurpose.CHANGE), utxoFilters, feeRate, longTermFeeRate, groupByAddress, includeMempoolInputs); + getGroupedUtxos(outputGroups, getNode(KeyPurpose.RECEIVE), utxoFilters, feeRate, longTermFeeRate, groupByAddress, includeSpentMempoolOutputs); + getGroupedUtxos(outputGroups, getNode(KeyPurpose.CHANGE), utxoFilters, feeRate, longTermFeeRate, groupByAddress, includeSpentMempoolOutputs); return outputGroups; } - private void getGroupedUtxos(List outputGroups, WalletNode purposeNode, List utxoFilters, double feeRate, double longTermFeeRate, boolean groupByAddress, boolean includeMempoolInputs) { + private void getGroupedUtxos(List outputGroups, WalletNode purposeNode, List utxoFilters, double feeRate, double longTermFeeRate, boolean groupByAddress, boolean includeSpentMempoolOutputs) { for(WalletNode addressNode : purposeNode.getChildren()) { OutputGroup outputGroup = null; - for(BlockTransactionHashIndex utxo : addressNode.getUnspentTransactionOutputs(includeMempoolInputs)) { + for(BlockTransactionHashIndex utxo : addressNode.getUnspentTransactionOutputs(includeSpentMempoolOutputs)) { Optional matchedFilter = utxoFilters.stream().filter(utxoFilter -> !utxoFilter.isEligible(utxo)).findAny(); if(matchedFilter.isPresent()) { continue; diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/WalletNode.java b/src/main/java/com/sparrowwallet/drongo/wallet/WalletNode.java index 2854d83..835e040 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/WalletNode.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/WalletNode.java @@ -116,9 +116,9 @@ public class WalletNode implements Comparable { return getUnspentTransactionOutputs(false); } - public Set getUnspentTransactionOutputs(boolean includeMempoolInputs) { + public Set getUnspentTransactionOutputs(boolean includeSpentMempoolOutputs) { Set unspentTXOs = new TreeSet<>(transactionOutputs); - return unspentTXOs.stream().filter(txo -> !txo.isSpent() || (includeMempoolInputs && txo.getSpentBy().getHeight() <= 0)).collect(Collectors.toCollection(HashSet::new)); + return unspentTXOs.stream().filter(txo -> !txo.isSpent() || (includeSpentMempoolOutputs && txo.getSpentBy().getHeight() <= 0)).collect(Collectors.toCollection(HashSet::new)); } public long getUnspentValue() { From b0d37fe8fe6a4bec756e8c24bee562d1a377cf10 Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Wed, 21 Apr 2021 09:53:53 +0200 Subject: [PATCH 022/155] include all utxos when sending max amount --- .../java/com/sparrowwallet/drongo/wallet/Wallet.java | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java index a9911d0..2599dee 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java @@ -461,11 +461,12 @@ public class Wallet { } public WalletTransaction createWalletTransaction(List utxoSelectors, List utxoFilters, List payments, double feeRate, double longTermFeeRate, Long fee, Integer currentBlockHeight, boolean groupByAddress, boolean includeMempoolOutputs, boolean includeSpentMempoolOutputs) throws InsufficientFundsException { + boolean sendMax = payments.stream().anyMatch(Payment::isSendMax); long totalPaymentAmount = payments.stream().map(Payment::getAmount).mapToLong(v -> v).sum(); long valueRequiredAmt = totalPaymentAmount; while(true) { - Map selectedUtxos = selectInputs(utxoSelectors, utxoFilters, valueRequiredAmt, feeRate, longTermFeeRate, groupByAddress, includeMempoolOutputs, includeSpentMempoolOutputs); + Map selectedUtxos = selectInputs(utxoSelectors, utxoFilters, valueRequiredAmt, feeRate, longTermFeeRate, groupByAddress, includeMempoolOutputs, includeSpentMempoolOutputs, sendMax); long totalSelectedAmt = selectedUtxos.keySet().stream().mapToLong(BlockTransactionHashIndex::getValue).sum(); Transaction transaction = new Transaction(); @@ -501,7 +502,7 @@ public class Wallet { throw new InsufficientFundsException("Not enough combined value in selected UTXOs for fee of " + noChangeFeeRequiredAmt); } - Optional optMaxPayment = payments.stream().filter(payment -> payment.isSendMax()).findFirst(); + Optional optMaxPayment = payments.stream().filter(Payment::isSendMax).findFirst(); if(optMaxPayment.isPresent()) { Payment maxPayment = optMaxPayment.get(); maxSendAmt = maxSendAmt - payments.stream().filter(payment -> !maxPayment.equals(payment)).map(Payment::getAmount).mapToLong(v -> v).sum(); @@ -567,7 +568,7 @@ public class Wallet { } } - private Map selectInputs(List utxoSelectors, List utxoFilters, Long targetValue, double feeRate, double longTermFeeRate, boolean groupByAddress, boolean includeMempoolOutputs, boolean includeSpentMempoolOutputs) throws InsufficientFundsException { + private Map selectInputs(List utxoSelectors, List utxoFilters, Long targetValue, double feeRate, double longTermFeeRate, boolean groupByAddress, boolean includeMempoolOutputs, boolean includeSpentMempoolOutputs, boolean sendMax) throws InsufficientFundsException { List utxoPool = getGroupedUtxos(utxoFilters, feeRate, longTermFeeRate, groupByAddress, includeSpentMempoolOutputs); List filters = new ArrayList<>(); @@ -577,6 +578,10 @@ public class Wallet { filters.add(new OutputGroup.Filter(0, 0)); } + if(sendMax) { + Collections.reverse(filters); + } + for(OutputGroup.Filter filter : filters) { List filteredPool = utxoPool.stream().filter(filter::isEligible).collect(Collectors.toList()); From 0a43f9f6a8d0fd849e6552b936f8d15fafe800fa Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Wed, 21 Apr 2021 13:08:22 +0200 Subject: [PATCH 023/155] dont increment fee if user set --- src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java index 2599dee..7884b21 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java @@ -494,7 +494,7 @@ public class Wallet { long noChangeFeeRequiredAmt = (fee == null ? (long)(feeRate * noChangeVSize) : fee); //Add 1 satoshi to accommodate longer signatures when feeRate equals default min relay fee to ensure fee is sufficient - noChangeFeeRequiredAmt = (feeRate == Transaction.DEFAULT_MIN_RELAY_FEE ? noChangeFeeRequiredAmt + 1 : noChangeFeeRequiredAmt); + noChangeFeeRequiredAmt = (fee == null && feeRate == Transaction.DEFAULT_MIN_RELAY_FEE ? noChangeFeeRequiredAmt + 1 : noChangeFeeRequiredAmt); //If sending all selected utxos, set the recipient amount to equal to total of those utxos less the no change fee long maxSendAmt = totalSelectedAmt - noChangeFeeRequiredAmt; @@ -531,7 +531,7 @@ public class Wallet { TransactionOutput changeOutput = new TransactionOutput(transaction, changeAmt, getOutputScript(changeNode)); double changeVSize = noChangeVSize + changeOutput.getLength(); long changeFeeRequiredAmt = (fee == null ? (long)(feeRate * changeVSize) : fee); - changeFeeRequiredAmt = (feeRate == Transaction.DEFAULT_MIN_RELAY_FEE ? changeFeeRequiredAmt + 1 : changeFeeRequiredAmt); + changeFeeRequiredAmt = (fee == null && feeRate == Transaction.DEFAULT_MIN_RELAY_FEE ? changeFeeRequiredAmt + 1 : changeFeeRequiredAmt); //Recalculate the change amount with the new fee changeAmt = differenceAmt - changeFeeRequiredAmt; From db05e09fe54d80d611153cc4326d83cc91359ffa Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Sat, 24 Apr 2021 08:55:33 +0200 Subject: [PATCH 024/155] verify segwit psbt partial signatures with only non-witness utxo provided --- .../java/com/sparrowwallet/drongo/psbt/PSBTInput.java | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/sparrowwallet/drongo/psbt/PSBTInput.java b/src/main/java/com/sparrowwallet/drongo/psbt/PSBTInput.java index 907efc3..bdd7645 100644 --- a/src/main/java/com/sparrowwallet/drongo/psbt/PSBTInput.java +++ b/src/main/java/com/sparrowwallet/drongo/psbt/PSBTInput.java @@ -555,12 +555,8 @@ public class PSBTInput { Sha256Hash hash; ScriptType scriptType = getScriptType(); - if(getWitnessUtxo() == null && Arrays.asList(WITNESS_TYPES).contains(scriptType)) { - throw new IllegalStateException("Trying to get signature hash for " + scriptType + " script without a PSBT witness UTXO"); - } - - if(getWitnessUtxo() != null) { - long prevValue = getWitnessUtxo().getValue(); + if(Arrays.asList(WITNESS_TYPES).contains(scriptType)) { + long prevValue = getUtxo().getValue(); hash = transaction.hashForWitnessSignature(index, connectedScript, prevValue, localSigHash); } else { hash = transaction.hashForLegacySignature(index, connectedScript, localSigHash); From 173743ba0d266cd75636df28e6f1aba4e95d4d96 Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Sun, 25 Apr 2021 12:22:38 +0200 Subject: [PATCH 025/155] ensure grinding for low R is done in the same way as libsecp256k1 so signatures match --- .../java/com/sparrowwallet/drongo/Utils.java | 12 +++++++---- .../sparrowwallet/drongo/crypto/ECKey.java | 7 ++++--- .../crypto/HMacDSANonceKCalculator.java | 21 +++++++++++++------ .../sparrowwallet/drongo/psbt/PSBTEntry.java | 10 +-------- 4 files changed, 28 insertions(+), 22 deletions(-) diff --git a/src/main/java/com/sparrowwallet/drongo/Utils.java b/src/main/java/com/sparrowwallet/drongo/Utils.java index 827e777..d45b9b3 100644 --- a/src/main/java/com/sparrowwallet/drongo/Utils.java +++ b/src/main/java/com/sparrowwallet/drongo/Utils.java @@ -12,10 +12,6 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.math.BigInteger; -import java.nio.Buffer; -import java.nio.ByteBuffer; -import java.nio.CharBuffer; -import java.nio.charset.StandardCharsets; import java.util.*; public class Utils { @@ -115,6 +111,14 @@ public class Utils { return dest; } + public static void reverse(byte[] array) { + for (int i = 0; i < array.length / 2; i++) { + byte temp = array[i]; + array[i] = array[array.length - i - 1]; + array[array.length - i - 1] = temp; + } + } + /** Parse 4 bytes from the byte array (starting at the offset) as unsigned 32-bit integer in little endian format. */ public static long readUint32(byte[] bytes, int offset) { return (bytes[offset] & 0xffl) | diff --git a/src/main/java/com/sparrowwallet/drongo/crypto/ECKey.java b/src/main/java/com/sparrowwallet/drongo/crypto/ECKey.java index e31442a..1075ef3 100644 --- a/src/main/java/com/sparrowwallet/drongo/crypto/ECKey.java +++ b/src/main/java/com/sparrowwallet/drongo/crypto/ECKey.java @@ -470,7 +470,8 @@ public class ECKey implements EncryptableItem { } protected boolean hasLowR() { - return r.toByteArray().length <= 32; + //A low R signature will have less than 71 bytes when encoded to DER + return toCanonicalised().encodeToDER().length < 71; } @Override @@ -530,14 +531,14 @@ public class ECKey implements EncryptableItem { } ECDSASignature signature; - int counter = 0; + Integer counter = null; do { ECDSASigner signer = new ECDSASigner(new HMacDSANonceKCalculator(new SHA256Digest(), counter)); ECPrivateKeyParameters privKey = new ECPrivateKeyParameters(privateKeyForSigning, CURVE); signer.init(true, privKey); BigInteger[] components = signer.generateSignature(input.getBytes()); signature = new ECDSASignature(components[0], components[1]).toCanonicalised(); - counter++; + counter = (counter == null ? 1 : counter+1); } while(!signature.hasLowR()); return signature; diff --git a/src/main/java/com/sparrowwallet/drongo/crypto/HMacDSANonceKCalculator.java b/src/main/java/com/sparrowwallet/drongo/crypto/HMacDSANonceKCalculator.java index 90aa721..ee1e499 100644 --- a/src/main/java/com/sparrowwallet/drongo/crypto/HMacDSANonceKCalculator.java +++ b/src/main/java/com/sparrowwallet/drongo/crypto/HMacDSANonceKCalculator.java @@ -21,7 +21,7 @@ public class HMacDSANonceKCalculator implements DSAKCalculator { private final HMac hMac; private final byte[] K; private final byte[] V; - private final long counter; + private final Long counter; private BigInteger n; @@ -31,11 +31,11 @@ public class HMacDSANonceKCalculator implements DSAKCalculator { * @param digest digest to build the HMAC on. * @param counter additional data as per RFC 6979 3.6 */ - public HMacDSANonceKCalculator(Digest digest, int counter) { + public HMacDSANonceKCalculator(Digest digest, Integer counter) { this.hMac = new HMac(digest); this.V = new byte[hMac.getMacSize()]; this.K = new byte[hMac.getMacSize()]; - this.counter = Integer.toUnsignedLong(counter); + this.counter = (counter == null ? null : Integer.toUnsignedLong(counter)); } public boolean isDeterministic() @@ -74,8 +74,12 @@ public class HMacDSANonceKCalculator implements DSAKCalculator { System.arraycopy(mVal, 0, m, m.length - mVal.length, mVal.length); - BigInteger additional = BigInteger.valueOf(counter); - byte[] aData = Utils.bigIntegerToBytes(additional, size); + byte[] c = null; + if(counter != null) { + BigInteger additional = BigInteger.valueOf(counter); + c = Utils.bigIntegerToBytes(additional, size); + Utils.reverse(c); + } hMac.init(new KeyParameter(K)); @@ -83,7 +87,9 @@ public class HMacDSANonceKCalculator implements DSAKCalculator { hMac.update((byte)0x00); hMac.update(x, 0, x.length); hMac.update(m, 0, m.length); - hMac.update(aData, 0, aData.length); + if(c != null) { + hMac.update(c, 0, c.length); + } hMac.doFinal(K, 0); @@ -97,6 +103,9 @@ public class HMacDSANonceKCalculator implements DSAKCalculator { hMac.update((byte)0x01); hMac.update(x, 0, x.length); hMac.update(m, 0, m.length); + if(counter != null) { + hMac.update(c, 0, c.length); + } hMac.doFinal(K, 0); diff --git a/src/main/java/com/sparrowwallet/drongo/psbt/PSBTEntry.java b/src/main/java/com/sparrowwallet/drongo/psbt/PSBTEntry.java index 2f80dbe..b505475 100644 --- a/src/main/java/com/sparrowwallet/drongo/psbt/PSBTEntry.java +++ b/src/main/java/com/sparrowwallet/drongo/psbt/PSBTEntry.java @@ -83,7 +83,7 @@ public class PSBTEntry { do { bb.get(buf); - reverse(buf); + Utils.reverse(buf); ByteBuffer pbuf = ByteBuffer.wrap(buf); path.add(new ChildNumber(pbuf.getInt())); } while(bb.hasRemaining()); @@ -202,14 +202,6 @@ public class PSBTEntry { return bb.array(); } - private static void reverse(byte[] array) { - for (int i = 0; i < array.length / 2; i++) { - byte temp = array[i]; - array[i] = array[array.length - i - 1]; - array[array.length - i - 1] = temp; - } - } - public void checkOneByteKey() throws PSBTParseException { if(this.getKey().length != 1) { throw new PSBTParseException("PSBT key type must be one byte"); From f4730f71471be716bdc925c98474421b06aa68aa Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Sun, 25 Apr 2021 13:25:04 +0200 Subject: [PATCH 026/155] add message sign test for low r grinding (verified signatures against electrum 4.1.2) --- .../drongo/crypto/ECKeyTest.java | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 src/test/java/com/sparrowwallet/drongo/crypto/ECKeyTest.java diff --git a/src/test/java/com/sparrowwallet/drongo/crypto/ECKeyTest.java b/src/test/java/com/sparrowwallet/drongo/crypto/ECKeyTest.java new file mode 100644 index 0000000..86860ab --- /dev/null +++ b/src/test/java/com/sparrowwallet/drongo/crypto/ECKeyTest.java @@ -0,0 +1,37 @@ +package com.sparrowwallet.drongo.crypto; + +import com.sparrowwallet.drongo.KeyPurpose; +import com.sparrowwallet.drongo.address.Address; +import com.sparrowwallet.drongo.policy.Policy; +import com.sparrowwallet.drongo.policy.PolicyType; +import com.sparrowwallet.drongo.protocol.ScriptType; +import com.sparrowwallet.drongo.wallet.*; +import org.junit.Assert; +import org.junit.Test; + +public class ECKeyTest { + @Test + public void testGrindLowR() throws MnemonicException { + String words = "absent essay fox snake vast pumpkin height crouch silent bulb excuse razor"; + DeterministicSeed seed = new DeterministicSeed(words, "", 0, DeterministicSeed.Type.BIP39); + Wallet wallet = new Wallet(); + wallet.setPolicyType(PolicyType.SINGLE); + wallet.setScriptType(ScriptType.P2PKH); + Keystore keystore = Keystore.fromSeed(seed, wallet.getScriptType().getDefaultDerivation()); + wallet.getKeystores().add(keystore); + wallet.setDefaultPolicy(Policy.getPolicy(PolicyType.SINGLE, ScriptType.P2PKH, wallet.getKeystores(), 1)); + + WalletNode firstReceive = wallet.getNode(KeyPurpose.RECEIVE).getChildren().iterator().next(); + Address address = wallet.getAddress(firstReceive); + Assert.assertEquals("14JmU9a7SzieZNEtBnsZo688rt3mGrw6hr", address.toString()); + ECKey privKey = keystore.getKey(firstReceive); + + //2 attempts required for low R + String signature = privKey.signMessage("Test", ScriptType.P2PKH, null); + Assert.assertEquals("IDgMx1ljPhLHlKUOwnO/jBIgK+K8n8mvDUDROzTgU8gOaPDMs+eYXJpNXXINUx5WpeV605p5uO6B3TzBVcvs478=", signature); + + //3 attempts required for low R + String signature2 = privKey.signMessage("Test1", ScriptType.P2PKH, null); + Assert.assertEquals("IEt/v9K95YVFuRtRtWaabPVwWOFv1FSA/e874I8ABgYMbRyVvHhSwLFz0RZuO87ukxDd4TOsRdofQwMEA90LCgI=", signature2); + } +} From cc6e3ffdc240e8d767ca4e6285f11c6f9ee72789 Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Sun, 25 Apr 2021 18:05:22 +0200 Subject: [PATCH 027/155] add message sign test for low r requiring only a single attempt --- .../com/sparrowwallet/drongo/crypto/ECKeyTest.java | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/test/java/com/sparrowwallet/drongo/crypto/ECKeyTest.java b/src/test/java/com/sparrowwallet/drongo/crypto/ECKeyTest.java index 86860ab..ecbeb1c 100644 --- a/src/test/java/com/sparrowwallet/drongo/crypto/ECKeyTest.java +++ b/src/test/java/com/sparrowwallet/drongo/crypto/ECKeyTest.java @@ -26,12 +26,16 @@ public class ECKeyTest { Assert.assertEquals("14JmU9a7SzieZNEtBnsZo688rt3mGrw6hr", address.toString()); ECKey privKey = keystore.getKey(firstReceive); + //1 attempt required for low R + String signature1 = privKey.signMessage("Test2", ScriptType.P2PKH, null); + Assert.assertEquals("IHra0jSywF1TjIJ5uf7IDECae438cr4o3VmG6Ri7hYlDL+pUEXyUfwLwpiAfUQVqQFLgs6OaX0KsoydpuwRI71o=", signature1); + //2 attempts required for low R - String signature = privKey.signMessage("Test", ScriptType.P2PKH, null); - Assert.assertEquals("IDgMx1ljPhLHlKUOwnO/jBIgK+K8n8mvDUDROzTgU8gOaPDMs+eYXJpNXXINUx5WpeV605p5uO6B3TzBVcvs478=", signature); + String signature2 = privKey.signMessage("Test", ScriptType.P2PKH, null); + Assert.assertEquals("IDgMx1ljPhLHlKUOwnO/jBIgK+K8n8mvDUDROzTgU8gOaPDMs+eYXJpNXXINUx5WpeV605p5uO6B3TzBVcvs478=", signature2); //3 attempts required for low R - String signature2 = privKey.signMessage("Test1", ScriptType.P2PKH, null); - Assert.assertEquals("IEt/v9K95YVFuRtRtWaabPVwWOFv1FSA/e874I8ABgYMbRyVvHhSwLFz0RZuO87ukxDd4TOsRdofQwMEA90LCgI=", signature2); + String signature3 = privKey.signMessage("Test1", ScriptType.P2PKH, null); + Assert.assertEquals("IEt/v9K95YVFuRtRtWaabPVwWOFv1FSA/e874I8ABgYMbRyVvHhSwLFz0RZuO87ukxDd4TOsRdofQwMEA90LCgI=", signature3); } } From 63394b142c0ddc3de07f5e25136dfd90355b7bf9 Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Mon, 26 Apr 2021 14:27:08 +0200 Subject: [PATCH 028/155] dont add inputs with negative effective value when calculating max value --- .../java/com/sparrowwallet/drongo/wallet/MaxUtxoSelector.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/MaxUtxoSelector.java b/src/main/java/com/sparrowwallet/drongo/wallet/MaxUtxoSelector.java index 787fa1f..ad14bbd 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/MaxUtxoSelector.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/MaxUtxoSelector.java @@ -6,6 +6,6 @@ import java.util.stream.Collectors; public class MaxUtxoSelector implements UtxoSelector { @Override public Collection select(long targetValue, Collection candidates) { - return candidates.stream().flatMap(outputGroup -> outputGroup.getUtxos().stream()).collect(Collectors.toUnmodifiableList()); + return candidates.stream().filter(outputGroup -> outputGroup.getEffectiveValue() >= 0).flatMap(outputGroup -> outputGroup.getUtxos().stream()).collect(Collectors.toUnmodifiableList()); } } From 2cd133bc1c4301c8b0b762f847f6259a50b86087 Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Mon, 26 Apr 2021 14:38:36 +0200 Subject: [PATCH 029/155] handle user defined fee amount better by requiring a fee rate of 1 sat/vb for utxo selectors --- .../sparrowwallet/drongo/wallet/Wallet.java | 62 ++++++++++++++++--- 1 file changed, 53 insertions(+), 9 deletions(-) diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java index 7884b21..41760e8 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java @@ -419,9 +419,9 @@ public class Wallet { } /** - * Return the number of vBytes required for an input created by this wallet. + * Return the number of weight units required for an input created by this wallet. * - * @return the number of vBytes + * @return the number of weight units (WU) */ public int getInputWeightUnits() { //Estimate assuming an input spending from a fresh receive node - it does not matter this node has no real utxos @@ -463,7 +463,19 @@ public class Wallet { public WalletTransaction createWalletTransaction(List utxoSelectors, List utxoFilters, List payments, double feeRate, double longTermFeeRate, Long fee, Integer currentBlockHeight, boolean groupByAddress, boolean includeMempoolOutputs, boolean includeSpentMempoolOutputs) throws InsufficientFundsException { boolean sendMax = payments.stream().anyMatch(Payment::isSendMax); long totalPaymentAmount = payments.stream().map(Payment::getAmount).mapToLong(v -> v).sum(); - long valueRequiredAmt = totalPaymentAmount; + long totalUtxoValue = getWalletUtxos().keySet().stream().mapToLong(BlockTransactionHashIndex::getValue).sum(); + + long maxSpendableAmt = getMaxSpendable(payments.stream().map(Payment::getAddress).collect(Collectors.toList()), feeRate); + if(maxSpendableAmt < 0) { + throw new InsufficientFundsException("Not enough combined value in all available UTXOs to send a transaction to the provided addresses at this fee rate"); + } + + //When a user fee is set, we can calculate the fees to spend all UTXOs because we assume all UTXOs are spendable at a fee rate of 1 sat/vB + //We can then add the user set fee less this amount as a "phantom payment amount" to the value required to find (which cannot include transaction fees) + long valueRequiredAmt = totalPaymentAmount + (fee != null ? fee - (totalUtxoValue - maxSpendableAmt) : 0); + if(maxSpendableAmt < valueRequiredAmt) { + throw new InsufficientFundsException("Not enough combined value in all available UTXOs to send a transaction to send the provided payments at the user set fee" + (fee == null ? " rate" : "")); + } while(true) { Map selectedUtxos = selectInputs(utxoSelectors, utxoFilters, valueRequiredAmt, feeRate, longTermFeeRate, groupByAddress, includeMempoolOutputs, includeSpentMempoolOutputs, sendMax); @@ -491,16 +503,13 @@ public class Wallet { } double noChangeVSize = transaction.getVirtualSize(); - long noChangeFeeRequiredAmt = (fee == null ? (long)(feeRate * noChangeVSize) : fee); + long noChangeFeeRequiredAmt = (fee == null ? (long)Math.floor(feeRate * noChangeVSize) : fee); //Add 1 satoshi to accommodate longer signatures when feeRate equals default min relay fee to ensure fee is sufficient noChangeFeeRequiredAmt = (fee == null && feeRate == Transaction.DEFAULT_MIN_RELAY_FEE ? noChangeFeeRequiredAmt + 1 : noChangeFeeRequiredAmt); //If sending all selected utxos, set the recipient amount to equal to total of those utxos less the no change fee long maxSendAmt = totalSelectedAmt - noChangeFeeRequiredAmt; - if(maxSendAmt < 0) { - throw new InsufficientFundsException("Not enough combined value in selected UTXOs for fee of " + noChangeFeeRequiredAmt); - } Optional optMaxPayment = payments.stream().filter(Payment::isSendMax).findFirst(); if(optMaxPayment.isPresent()) { @@ -519,18 +528,23 @@ public class Wallet { //If insufficient fee, increase value required from inputs to include the fee and try again if(differenceAmt < noChangeFeeRequiredAmt) { valueRequiredAmt = totalSelectedAmt + 1; + if(valueRequiredAmt > maxSpendableAmt && transaction.getInputs().size() < getWalletUtxos().size()) { + valueRequiredAmt = maxSpendableAmt; + } + continue; } //Determine if a change output is required by checking if its value is greater than its dust threshold long changeAmt = differenceAmt - noChangeFeeRequiredAmt; - long costOfChangeAmt = getCostOfChange(feeRate, longTermFeeRate); + double noChangeFeeRate = (fee == null ? feeRate : noChangeFeeRequiredAmt / transaction.getVirtualSize()); + long costOfChangeAmt = getCostOfChange(noChangeFeeRate, longTermFeeRate); if(changeAmt > costOfChangeAmt) { //Change output is required, determine new fee once change output has been added WalletNode changeNode = getFreshNode(KeyPurpose.CHANGE); TransactionOutput changeOutput = new TransactionOutput(transaction, changeAmt, getOutputScript(changeNode)); double changeVSize = noChangeVSize + changeOutput.getLength(); - long changeFeeRequiredAmt = (fee == null ? (long)(feeRate * changeVSize) : fee); + long changeFeeRequiredAmt = (fee == null ? (long)Math.floor(feeRate * changeVSize) : fee); changeFeeRequiredAmt = (fee == null && feeRate == Transaction.DEFAULT_MIN_RELAY_FEE ? changeFeeRequiredAmt + 1 : changeFeeRequiredAmt); //Recalculate the change amount with the new fee @@ -657,6 +671,36 @@ public class Wallet { return true; } + /** + * Determines the maximum total amount this wallet can send for the number and type of addresses at the given fee rate + * + * @param paymentAddresses the addresses to sent to (amounts are irrelevant) + * @param feeRate the fee rate in sats/vB + * @return the maximum spendable amount (can be negative if the fee is higher than the combined UTXO value) + */ + public long getMaxSpendable(List
paymentAddresses, double feeRate) { + long maxInputValue = 0; + int inputWeightUnits = getInputWeightUnits(); + long minInputValue = (long)Math.ceil(feeRate * inputWeightUnits / WITNESS_SCALE_FACTOR); + + Transaction transaction = new Transaction(); + for(Map.Entry utxo : getWalletUtxos().entrySet()) { + if(utxo.getKey().getValue() > minInputValue) { + Transaction prevTx = getTransactions().get(utxo.getKey().getHash()).getTransaction(); + TransactionOutput prevTxOut = prevTx.getOutputs().get((int)utxo.getKey().getIndex()); + addDummySpendingInput(transaction, utxo.getValue(), prevTxOut); + maxInputValue += utxo.getKey().getValue(); + } + } + + for(Address address : paymentAddresses) { + transaction.addOutput(1L, address); + } + + long fee = (long)Math.floor(transaction.getVirtualSize() * feeRate); + return maxInputValue - fee; + } + public boolean canSign(Transaction transaction) { return isValid() && !getSigningNodes(transaction).isEmpty(); } From db9617ee10383bb78e71ec2252d92bb7fe639440 Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Mon, 26 Apr 2021 14:39:13 +0200 Subject: [PATCH 030/155] handle user defined fee amount better by requiring a fee rate of 1 sat/vb for utxo selectors --- src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java index 41760e8..be96a5e 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java @@ -465,6 +465,10 @@ public class Wallet { long totalPaymentAmount = payments.stream().map(Payment::getAmount).mapToLong(v -> v).sum(); long totalUtxoValue = getWalletUtxos().keySet().stream().mapToLong(BlockTransactionHashIndex::getValue).sum(); + if(fee != null && feeRate != Transaction.DEFAULT_MIN_RELAY_FEE) { + throw new IllegalArgumentException("Use an input fee rate of 1 sat/vB when using a defined fee amount so UTXO selectors overestimate effective value"); + } + long maxSpendableAmt = getMaxSpendable(payments.stream().map(Payment::getAddress).collect(Collectors.toList()), feeRate); if(maxSpendableAmt < 0) { throw new InsufficientFundsException("Not enough combined value in all available UTXOs to send a transaction to the provided addresses at this fee rate"); @@ -528,6 +532,7 @@ public class Wallet { //If insufficient fee, increase value required from inputs to include the fee and try again if(differenceAmt < noChangeFeeRequiredAmt) { valueRequiredAmt = totalSelectedAmt + 1; + //If we haven't selected all UTXOs yet, don't require more than the max spendable amount if(valueRequiredAmt > maxSpendableAmt && transaction.getInputs().size() < getWalletUtxos().size()) { valueRequiredAmt = maxSpendableAmt; } From cc32285d58fcd1120b27797ff1d882ae4ae8a1ed Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Thu, 6 May 2021 14:20:58 +0200 Subject: [PATCH 031/155] add helper to construct payment from bitcoin uri --- src/main/java/com/sparrowwallet/drongo/uri/BitcoinURI.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/main/java/com/sparrowwallet/drongo/uri/BitcoinURI.java b/src/main/java/com/sparrowwallet/drongo/uri/BitcoinURI.java index 68d5aa6..055ece0 100644 --- a/src/main/java/com/sparrowwallet/drongo/uri/BitcoinURI.java +++ b/src/main/java/com/sparrowwallet/drongo/uri/BitcoinURI.java @@ -2,6 +2,7 @@ package com.sparrowwallet.drongo.uri; import com.sparrowwallet.drongo.address.Address; import com.sparrowwallet.drongo.address.InvalidAddressException; +import com.sparrowwallet.drongo.wallet.Payment; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -325,6 +326,11 @@ public class BitcoinURI { return builder.toString(); } + public Payment toPayment() { + long amount = getAmount() == null ? -1 : getAmount(); + return new Payment(getAddress(), getLabel(), amount, false); + } + /** * Constructs a new BitcoinURI from the given address. * From 7dca0d0c39404bd89a5a4589a79ffe0f688e8181 Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Fri, 14 May 2021 12:54:31 +0200 Subject: [PATCH 032/155] add master wallet reference --- .../java/com/sparrowwallet/drongo/wallet/Wallet.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java index be96a5e..ce27bba 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java @@ -24,6 +24,7 @@ public class Wallet { public static final String ALLOW_DERIVATIONS_MATCHING_OTHER_SCRIPT_TYPES_PROPERTY = "com.sparrowwallet.allowDerivationsMatchingOtherScriptTypes"; private String name; + private Wallet masterWallet; private Network network = Network.get(); private PolicyType policyType; private ScriptType scriptType; @@ -140,6 +141,14 @@ public class Wallet { this.birthDate = birthDate; } + public Wallet getMasterWallet() { + return masterWallet; + } + + public void setMasterWallet(Wallet masterWallet) { + this.masterWallet = masterWallet; + } + public synchronized WalletNode getNode(KeyPurpose keyPurpose) { WalletNode purposeNode; Optional optionalPurposeNode = purposeNodes.stream().filter(node -> node.getKeyPurpose().equals(keyPurpose)).findFirst(); From 567294a4b055cc062650de45fccbbc89db714f39 Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Mon, 17 May 2021 13:20:43 +0200 Subject: [PATCH 033/155] support creating a transaction excluding the provided change addresses --- src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java index ce27bba..89114f0 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java @@ -469,7 +469,7 @@ public class Wallet { return getFee(changeOutput, feeRate, longTermFeeRate); } - public WalletTransaction createWalletTransaction(List utxoSelectors, List utxoFilters, List payments, double feeRate, double longTermFeeRate, Long fee, Integer currentBlockHeight, boolean groupByAddress, boolean includeMempoolOutputs, boolean includeSpentMempoolOutputs) throws InsufficientFundsException { + public WalletTransaction createWalletTransaction(List utxoSelectors, List utxoFilters, List payments, List excludedChangeNodes, double feeRate, double longTermFeeRate, Long fee, Integer currentBlockHeight, boolean groupByAddress, boolean includeMempoolOutputs, boolean includeSpentMempoolOutputs) throws InsufficientFundsException { boolean sendMax = payments.stream().anyMatch(Payment::isSendMax); long totalPaymentAmount = payments.stream().map(Payment::getAmount).mapToLong(v -> v).sum(); long totalUtxoValue = getWalletUtxos().keySet().stream().mapToLong(BlockTransactionHashIndex::getValue).sum(); @@ -556,6 +556,9 @@ public class Wallet { if(changeAmt > costOfChangeAmt) { //Change output is required, determine new fee once change output has been added WalletNode changeNode = getFreshNode(KeyPurpose.CHANGE); + while(excludedChangeNodes.contains(changeNode)) { + changeNode = getFreshNode(KeyPurpose.CHANGE, changeNode); + } TransactionOutput changeOutput = new TransactionOutput(transaction, changeAmt, getOutputScript(changeNode)); double changeVSize = noChangeVSize + changeOutput.getLength(); long changeFeeRequiredAmt = (fee == null ? (long)Math.floor(feeRate * changeVSize) : fee); From 42ffeb95650c56bffbd5ec8f8e8f38d91faaab3f Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Fri, 28 May 2021 11:07:59 +0200 Subject: [PATCH 034/155] allow psbt signature verification to be deferred --- .../com/sparrowwallet/drongo/psbt/PSBT.java | 43 ++++++++++++++----- .../sparrowwallet/drongo/psbt/PSBTInput.java | 20 +++++---- .../drongo/psbt/PSBTSignatureException.java | 19 ++++++++ 3 files changed, 64 insertions(+), 18 deletions(-) create mode 100644 src/main/java/com/sparrowwallet/drongo/psbt/PSBTSignatureException.java diff --git a/src/main/java/com/sparrowwallet/drongo/psbt/PSBT.java b/src/main/java/com/sparrowwallet/drongo/psbt/PSBT.java index 14f3086..38af19c 100644 --- a/src/main/java/com/sparrowwallet/drongo/psbt/PSBT.java +++ b/src/main/java/com/sparrowwallet/drongo/psbt/PSBT.java @@ -16,7 +16,7 @@ import java.nio.ByteBuffer; import java.util.*; import static com.sparrowwallet.drongo.psbt.PSBTEntry.*; -import static com.sparrowwallet.drongo.psbt.PSBTInput.PSBT_IN_BIP32_DERIVATION; +import static com.sparrowwallet.drongo.psbt.PSBTInput.*; import static com.sparrowwallet.drongo.psbt.PSBTOutput.*; public class PSBT { @@ -169,11 +169,15 @@ public class PSBT { } public PSBT(byte[] psbt) throws PSBTParseException { - this.psbtBytes = psbt; - parse(); + this(psbt, true); } - private void parse() throws PSBTParseException { + public PSBT(byte[] psbt, boolean verifySignatures) throws PSBTParseException { + this.psbtBytes = psbt; + parse(verifySignatures); + } + + private void parse(boolean verifySignatures) throws PSBTParseException { int seenInputs = 0; int seenOutputs = 0; @@ -214,7 +218,7 @@ public class PSBT { seenInputs++; if (seenInputs == inputs) { currentState = STATE_OUTPUTS; - parseInputEntries(inputEntryLists); + parseInputEntries(inputEntryLists, verifySignatures); } break; case STATE_OUTPUTS: @@ -315,7 +319,7 @@ public class PSBT { } } - private void parseInputEntries(List> inputEntryLists) throws PSBTParseException { + private void parseInputEntries(List> inputEntryLists, boolean verifySignatures) throws PSBTParseException { for(List inputEntries : inputEntryLists) { PSBTEntry duplicate = findDuplicateKey(inputEntries); if(duplicate != null) { @@ -325,9 +329,11 @@ public class PSBT { int inputIndex = this.psbtInputs.size(); PSBTInput input = new PSBTInput(inputEntries, transaction, inputIndex); - boolean verified = input.verifySignatures(); - if(!verified && input.getPartialSignatures().size() > 0) { - throw new PSBTParseException("Unverifiable partial signatures provided"); + if(verifySignatures) { + boolean verified = input.verifySignatures(); + if(!verified && input.getPartialSignatures().size() > 0) { + throw new PSBTSignatureException("Unverifiable partial signatures provided"); + } } this.psbtInputs.add(input); @@ -379,6 +385,19 @@ public class PSBT { return fee; } + public void verifySignatures() throws PSBTSignatureException { + for(PSBTInput input : getPsbtInputs()) { + boolean verified = input.verifySignatures(); + if(!verified) { + if(input.getPartialSignatures().size() > 0) { + throw new PSBTSignatureException("Unverifiable partial signatures provided"); + } + + throw new PSBTSignatureException("No UTXO data provided"); + } + } + } + public boolean hasSignatures() { for(PSBTInput psbtInput : getPsbtInputs()) { if(!psbtInput.getPartialSignatures().isEmpty() || psbtInput.getFinalScriptSig() != null || psbtInput.getFinalScriptWitness() != null) { @@ -630,6 +649,10 @@ public class PSBT { } public static PSBT fromString(String strPSBT) throws PSBTParseException { + return fromString(strPSBT, true); + } + + public static PSBT fromString(String strPSBT, boolean verifySignatures) throws PSBTParseException { if (!isPSBT(strPSBT)) { throw new PSBTParseException("Provided string is not a PSBT"); } @@ -639,6 +662,6 @@ public class PSBT { } byte[] psbtBytes = Utils.hexToBytes(strPSBT); - return new PSBT(psbtBytes); + return new PSBT(psbtBytes, verifySignatures); } } diff --git a/src/main/java/com/sparrowwallet/drongo/psbt/PSBTInput.java b/src/main/java/com/sparrowwallet/drongo/psbt/PSBTInput.java index bdd7645..a569328 100644 --- a/src/main/java/com/sparrowwallet/drongo/psbt/PSBTInput.java +++ b/src/main/java/com/sparrowwallet/drongo/psbt/PSBTInput.java @@ -136,11 +136,15 @@ public class PSBTInput { throw new PSBTParseException("Witness UTXO provided but redeem script is not P2WPKH or P2WSH"); } } - if(scriptPubKey == null || !P2SH.isScriptType(scriptPubKey)) { - throw new PSBTParseException("PSBT provided a redeem script for a transaction output that does not need one"); - } - if(!Arrays.equals(Utils.sha256hash160(redeemScript.getProgram()), scriptPubKey.getPubKeyHash())) { - throw new PSBTParseException("Redeem script hash does not match transaction output script pubkey hash " + Utils.bytesToHex(scriptPubKey.getPubKeyHash())); + if(scriptPubKey == null) { + log.warn("PSBT provided a redeem script for a transaction output that was not provided"); + } else { + if(!P2SH.isScriptType(scriptPubKey)) { + throw new PSBTParseException("PSBT provided a redeem script for a transaction output that does not need one"); + } + if(!Arrays.equals(Utils.sha256hash160(redeemScript.getProgram()), scriptPubKey.getPubKeyHash())) { + throw new PSBTParseException("Redeem script hash does not match transaction output script pubkey hash " + Utils.bytesToHex(scriptPubKey.getPubKeyHash())); + } } this.redeemScript = redeemScript; @@ -156,7 +160,7 @@ public class PSBTInput { pubKeyHash = this.witnessUtxo.getScript().getPubKeyHash(); } if(pubKeyHash == null) { - throw new PSBTParseException("Witness script provided without P2WSH witness utxo or P2SH redeem script"); + log.warn("Witness script provided without P2WSH witness utxo or P2SH redeem script"); } else if(!Arrays.equals(Sha256Hash.hash(witnessScript.getProgram()), pubKeyHash)) { throw new PSBTParseException("Witness script hash does not match provided pay to script hash " + Utils.bytesToHex(pubKeyHash)); } @@ -428,7 +432,7 @@ public class PSBTInput { return false; } - boolean verifySignatures() throws PSBTParseException { + boolean verifySignatures() throws PSBTSignatureException { SigHash localSigHash = getSigHash(); if(localSigHash == null) { //Assume SigHash.ALL @@ -443,7 +447,7 @@ public class PSBTInput { for(ECKey sigPublicKey : getPartialSignatures().keySet()) { TransactionSignature signature = getPartialSignature(sigPublicKey); if(!sigPublicKey.verify(hash, signature)) { - throw new PSBTParseException("Partial signature does not verify against provided public key"); + throw new PSBTSignatureException("Partial signature does not verify against provided public key"); } } diff --git a/src/main/java/com/sparrowwallet/drongo/psbt/PSBTSignatureException.java b/src/main/java/com/sparrowwallet/drongo/psbt/PSBTSignatureException.java new file mode 100644 index 0000000..a29f686 --- /dev/null +++ b/src/main/java/com/sparrowwallet/drongo/psbt/PSBTSignatureException.java @@ -0,0 +1,19 @@ +package com.sparrowwallet.drongo.psbt; + +public class PSBTSignatureException extends PSBTParseException { + public PSBTSignatureException() { + super(); + } + + public PSBTSignatureException(String message) { + super(message); + } + + public PSBTSignatureException(Throwable cause) { + super(cause); + } + + public PSBTSignatureException(String message, Throwable cause) { + super(message, cause); + } +} From 8e3d0d23c129b7fe9eedb16769827155f53c84d5 Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Thu, 10 Jun 2021 12:07:20 +0200 Subject: [PATCH 035/155] support database persistence --- build.gradle | 2 ++ .../sparrowwallet/drongo/policy/Policy.java | 11 ++++-- .../drongo/wallet/BlockTransactionHash.java | 2 +- .../wallet/BlockTransactionHashIndex.java | 4 ++- .../drongo/wallet/DeterministicSeed.java | 3 +- .../sparrowwallet/drongo/wallet/Keystore.java | 3 +- .../wallet/MasterPrivateExtendedKey.java | 10 ++++-- .../drongo/wallet/Persistable.java | 13 +++++++ .../sparrowwallet/drongo/wallet/Wallet.java | 34 ++++++++++++++++++- .../drongo/wallet/WalletNode.java | 7 ++-- src/main/java/module-info.java | 2 +- 11 files changed, 77 insertions(+), 14 deletions(-) create mode 100644 src/main/java/com/sparrowwallet/drongo/wallet/Persistable.java diff --git a/build.gradle b/build.gradle index ae5cca6..d6be80e 100644 --- a/build.gradle +++ b/build.gradle @@ -55,7 +55,9 @@ dependencies { } implementation ('ch.qos.logback:logback-classic:1.2.3') { exclude group: 'org.hamcrest', module: 'hamcrest-core' + exclude group: 'org.slf4j' } + implementation ('org.slf4j:slf4j-api:1.7.30') testImplementation ('junit:junit:4.12') { exclude group: 'org.hamcrest', module: 'hamcrest-core' } diff --git a/src/main/java/com/sparrowwallet/drongo/policy/Policy.java b/src/main/java/com/sparrowwallet/drongo/policy/Policy.java index b6991a2..370a111 100644 --- a/src/main/java/com/sparrowwallet/drongo/policy/Policy.java +++ b/src/main/java/com/sparrowwallet/drongo/policy/Policy.java @@ -2,13 +2,14 @@ package com.sparrowwallet.drongo.policy; import com.sparrowwallet.drongo.protocol.ScriptType; import com.sparrowwallet.drongo.wallet.Keystore; +import com.sparrowwallet.drongo.wallet.Persistable; import java.util.List; import static com.sparrowwallet.drongo.protocol.ScriptType.*; import static com.sparrowwallet.drongo.policy.PolicyType.*; -public class Policy { +public class Policy extends Persistable { private static final String DEFAULT_NAME = "Default"; private String name; @@ -23,6 +24,10 @@ public class Policy { this.miniscript = miniscript; } + public String getName() { + return name; + } + public Miniscript getMiniscript() { return miniscript; } @@ -57,6 +62,8 @@ public class Policy { } public Policy copy() { - return new Policy(name, miniscript.copy()); + Policy policy = new Policy(name, miniscript.copy()); + policy.setId(getId()); + return policy; } } diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/BlockTransactionHash.java b/src/main/java/com/sparrowwallet/drongo/wallet/BlockTransactionHash.java index 09af7c2..daa2231 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/BlockTransactionHash.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/BlockTransactionHash.java @@ -5,7 +5,7 @@ import com.sparrowwallet.drongo.protocol.Sha256Hash; import java.util.Date; import java.util.Objects; -public abstract class BlockTransactionHash { +public abstract class BlockTransactionHash extends Persistable { public static final int BLOCKS_TO_CONFIRM = 6; public static final int BLOCKS_TO_FULLY_CONFIRM = 100; diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/BlockTransactionHashIndex.java b/src/main/java/com/sparrowwallet/drongo/wallet/BlockTransactionHashIndex.java index 2046c38..30010a6 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/BlockTransactionHashIndex.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/BlockTransactionHashIndex.java @@ -96,6 +96,8 @@ public class BlockTransactionHashIndex extends BlockTransactionHash implements C } public BlockTransactionHashIndex copy() { - return new BlockTransactionHashIndex(super.getHash(), super.getHeight(), super.getDate(), super.getFee(), index, value, spentBy == null ? null : spentBy.copy(), super.getLabel()); + BlockTransactionHashIndex copy = new BlockTransactionHashIndex(super.getHash(), super.getHeight(), super.getDate(), super.getFee(), index, value, spentBy == null ? null : spentBy.copy(), super.getLabel()); + copy.setId(getId()); + return copy; } } diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/DeterministicSeed.java b/src/main/java/com/sparrowwallet/drongo/wallet/DeterministicSeed.java index 3dbb34a..6005f95 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/DeterministicSeed.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/DeterministicSeed.java @@ -7,7 +7,7 @@ import com.sparrowwallet.drongo.crypto.*; import java.security.SecureRandom; import java.util.*; -public class DeterministicSeed implements EncryptableItem { +public class DeterministicSeed extends Persistable implements EncryptableItem { public static final int DEFAULT_SEED_ENTROPY_BITS = 128; public static final int MAX_SEED_ENTROPY_BITS = 512; @@ -341,6 +341,7 @@ public class DeterministicSeed implements EncryptableItem { seed = new DeterministicSeed(new ArrayList<>(mnemonicCode), needsPassphrase, creationTimeSeconds, type); } + seed.setId(getId()); seed.setPassphrase(passphrase); return seed; } diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/Keystore.java b/src/main/java/com/sparrowwallet/drongo/wallet/Keystore.java index e8d2614..db40a68 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/Keystore.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/Keystore.java @@ -8,7 +8,7 @@ import com.sparrowwallet.drongo.crypto.*; import java.util.List; -public class Keystore { +public class Keystore extends Persistable { public static final String DEFAULT_LABEL = "Keystore 1"; public static final int MAX_LABEL_LENGTH = 16; @@ -229,6 +229,7 @@ public class Keystore { public Keystore copy() { Keystore copy = new Keystore(label); + copy.setId(getId()); copy.setSource(source); copy.setWalletModel(walletModel); if(keyDerivation != null) { diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/MasterPrivateExtendedKey.java b/src/main/java/com/sparrowwallet/drongo/wallet/MasterPrivateExtendedKey.java index efd99b4..e36d08c 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/MasterPrivateExtendedKey.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/MasterPrivateExtendedKey.java @@ -6,7 +6,7 @@ import com.sparrowwallet.drongo.crypto.*; import java.nio.ByteBuffer; import java.util.Arrays; -public class MasterPrivateExtendedKey implements EncryptableItem { +public class MasterPrivateExtendedKey extends Persistable implements EncryptableItem { private final byte[] privateKey; private final byte[] chainCode; @@ -112,11 +112,15 @@ public class MasterPrivateExtendedKey implements EncryptableItem { } public MasterPrivateExtendedKey copy() { + MasterPrivateExtendedKey copy; if(isEncrypted()) { - return new MasterPrivateExtendedKey(encryptedKey.copy()); + copy = new MasterPrivateExtendedKey(encryptedKey.copy()); + } else { + copy = new MasterPrivateExtendedKey(Arrays.copyOf(privateKey, 32), Arrays.copyOf(chainCode, 32)); } - return new MasterPrivateExtendedKey(Arrays.copyOf(privateKey, 32), Arrays.copyOf(chainCode, 32)); + copy.setId(getId()); + return copy; } public void clear() { diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/Persistable.java b/src/main/java/com/sparrowwallet/drongo/wallet/Persistable.java new file mode 100644 index 0000000..9d6712f --- /dev/null +++ b/src/main/java/com/sparrowwallet/drongo/wallet/Persistable.java @@ -0,0 +1,13 @@ +package com.sparrowwallet.drongo.wallet; + +public class Persistable { + private Long id; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } +} diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java index 89114f0..1254bbe 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java @@ -19,12 +19,13 @@ import java.util.stream.Collectors; import static com.sparrowwallet.drongo.protocol.ScriptType.*; import static com.sparrowwallet.drongo.protocol.Transaction.WITNESS_SCALE_FACTOR; -public class Wallet { +public class Wallet extends Persistable { public static final int DEFAULT_LOOKAHEAD = 20; public static final String ALLOW_DERIVATIONS_MATCHING_OTHER_SCRIPT_TYPES_PROPERTY = "com.sparrowwallet.allowDerivationsMatchingOtherScriptTypes"; private String name; private Wallet masterWallet; + private List childWallets = new ArrayList<>(); private Network network = Network.get(); private PolicyType policyType; private ScriptType scriptType; @@ -125,10 +126,18 @@ public class Wallet { this.storedBlockHeight = storedBlockHeight; } + public Integer gapLimit() { + return gapLimit; + } + public int getGapLimit() { return gapLimit == null ? DEFAULT_LOOKAHEAD : gapLimit; } + public void gapLimit(Integer gapLimit) { + this.gapLimit = gapLimit; + } + public void setGapLimit(int gapLimit) { this.gapLimit = gapLimit; } @@ -141,6 +150,10 @@ public class Wallet { this.birthDate = birthDate; } + public boolean isMasterWallet() { + return masterWallet == null; + } + public Wallet getMasterWallet() { return masterWallet; } @@ -149,6 +162,22 @@ public class Wallet { this.masterWallet = masterWallet; } + public Wallet getChildWallet(String name) { + return childWallets.stream().filter(wallet -> wallet.getName().equals(name)).findFirst().orElse(null); + } + + public List getChildWallets() { + return childWallets; + } + + public void setChildWallets(List childWallets) { + this.childWallets = childWallets; + } + + public TreeSet getPurposeNodes() { + return purposeNodes; + } + public synchronized WalletNode getNode(KeyPurpose keyPurpose) { WalletNode purposeNode; Optional optionalPurposeNode = purposeNodes.stream().filter(node -> node.getKeyPurpose().equals(keyPurpose)).findFirst(); @@ -1108,6 +1137,9 @@ public class Wallet { public Wallet copy() { Wallet copy = new Wallet(name); + copy.setId(getId()); + copy.setMasterWallet(masterWallet); + copy.setChildWallets(childWallets); copy.setPolicyType(policyType); copy.setScriptType(scriptType); copy.setDefaultPolicy(defaultPolicy.copy()); diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/WalletNode.java b/src/main/java/com/sparrowwallet/drongo/wallet/WalletNode.java index 835e040..d97cc17 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/WalletNode.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/WalletNode.java @@ -7,7 +7,7 @@ import com.sparrowwallet.drongo.crypto.ChildNumber; import java.util.*; import java.util.stream.Collectors; -public class WalletNode implements Comparable { +public class WalletNode extends Persistable implements Comparable { private final String derivationPath; private String label; private TreeSet children = new TreeSet<>(); @@ -87,7 +87,7 @@ public class WalletNode implements Comparable { } public Set getChildren() { - return children == null ? null : Collections.unmodifiableSet(children); + return children; } public void setChildren(TreeSet children) { @@ -95,7 +95,7 @@ public class WalletNode implements Comparable { } public Set getTransactionOutputs() { - return transactionOutputs == null ? null : Collections.unmodifiableSet(transactionOutputs); + return transactionOutputs; } public void setTransactionOutputs(TreeSet transactionOutputs) { @@ -195,6 +195,7 @@ public class WalletNode implements Comparable { public WalletNode copy() { WalletNode copy = new WalletNode(derivationPath); + copy.setId(getId()); copy.setLabel(label); for(WalletNode child : getChildren()) { diff --git a/src/main/java/module-info.java b/src/main/java/module-info.java index af29d6a..d287fa9 100644 --- a/src/main/java/module-info.java +++ b/src/main/java/module-info.java @@ -1,7 +1,7 @@ open module com.sparrowwallet.drongo { requires org.bouncycastle.provider; requires de.mkammerer.argon2; - requires slf4j.api; + requires org.slf4j; requires logback.core; requires logback.classic; requires json.simple; From 485e8c825b3beb9dc4bda3f3c2667264915dfd28 Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Thu, 10 Jun 2021 16:46:22 +0200 Subject: [PATCH 036/155] add keystone wallet --- src/main/java/com/sparrowwallet/drongo/wallet/WalletModel.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/WalletModel.java b/src/main/java/com/sparrowwallet/drongo/wallet/WalletModel.java index e71b676..5579e6e 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/WalletModel.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/WalletModel.java @@ -1,7 +1,7 @@ package com.sparrowwallet.drongo.wallet; public enum WalletModel { - SEED, SPARROW, BITCOIN_CORE, ELECTRUM, TREZOR_1, TREZOR_T, COLDCARD, LEDGER_NANO_S, LEDGER_NANO_X, DIGITALBITBOX_01, KEEPKEY, SPECTER_DESKTOP, COBO_VAULT, BITBOX_02, SPECTER_DIY, PASSPORT, BLUE_WALLET; + SEED, SPARROW, BITCOIN_CORE, ELECTRUM, TREZOR_1, TREZOR_T, COLDCARD, LEDGER_NANO_S, LEDGER_NANO_X, DIGITALBITBOX_01, KEEPKEY, SPECTER_DESKTOP, COBO_VAULT, BITBOX_02, SPECTER_DIY, PASSPORT, BLUE_WALLET, KEYSTONE; public static WalletModel getModel(String model) { return valueOf(model.toUpperCase()); From f407547c4766fd81cea29768e275c250b06cf968 Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Mon, 14 Jun 2021 14:53:53 +0200 Subject: [PATCH 037/155] preserve id when encrypting or decrypting seeds or private keys --- .../drongo/wallet/DeterministicSeed.java | 3 +++ .../drongo/wallet/MasterPrivateExtendedKey.java | 14 ++++++++++---- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/DeterministicSeed.java b/src/main/java/com/sparrowwallet/drongo/wallet/DeterministicSeed.java index 6005f95..841d905 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/DeterministicSeed.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/DeterministicSeed.java @@ -184,6 +184,7 @@ public class DeterministicSeed extends Persistable implements EncryptableItem { Arrays.fill(mnemonicBytes != null ? mnemonicBytes : new byte[0], (byte)0); DeterministicSeed seed = new DeterministicSeed(encryptedMnemonic, needsPassphrase, creationTimeSeconds, type); + seed.setId(getId()); seed.setPassphrase(passphrase); return seed; @@ -209,6 +210,7 @@ public class DeterministicSeed extends Persistable implements EncryptableItem { KeyDeriver keyDeriver = getEncryptionType().getDeriver().getKeyDeriver(encryptedMnemonicCode.getKeySalt()); Key key = keyDeriver.deriveKey(password); DeterministicSeed seed = decrypt(key); + seed.setId(getId()); key.clear(); return seed; @@ -225,6 +227,7 @@ public class DeterministicSeed extends Persistable implements EncryptableItem { Arrays.fill(decrypted, (byte)0); DeterministicSeed seed = new DeterministicSeed(mnemonic, needsPassphrase, creationTimeSeconds, type); + seed.setId(getId()); seed.setPassphrase(passphrase); return seed; diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/MasterPrivateExtendedKey.java b/src/main/java/com/sparrowwallet/drongo/wallet/MasterPrivateExtendedKey.java index e36d08c..4f5520a 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/MasterPrivateExtendedKey.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/MasterPrivateExtendedKey.java @@ -81,7 +81,10 @@ public class MasterPrivateExtendedKey extends Persistable implements Encryptable EncryptedData encryptedKeyData = keyCrypter.encrypt(secretBytes, null, key); Arrays.fill(secretBytes != null ? secretBytes : new byte[0], (byte)0); - return new MasterPrivateExtendedKey(encryptedKeyData); + MasterPrivateExtendedKey mpek = new MasterPrivateExtendedKey(encryptedKeyData); + mpek.setId(getId()); + + return mpek; } public MasterPrivateExtendedKey decrypt(CharSequence password) { @@ -91,10 +94,11 @@ public class MasterPrivateExtendedKey extends Persistable implements Encryptable KeyDeriver keyDeriver = getEncryptionType().getDeriver().getKeyDeriver(encryptedKey.getKeySalt()); Key key = keyDeriver.deriveKey(password); - MasterPrivateExtendedKey seed = decrypt(key); + MasterPrivateExtendedKey mpek = decrypt(key); + mpek.setId(getId()); key.clear(); - return seed; + return mpek; } public MasterPrivateExtendedKey decrypt(Key key) { @@ -105,7 +109,9 @@ public class MasterPrivateExtendedKey extends Persistable implements Encryptable KeyCrypter keyCrypter = getEncryptionType().getCrypter().getKeyCrypter(); byte[] decrypted = keyCrypter.decrypt(encryptedKey, key); try { - return new MasterPrivateExtendedKey(Arrays.copyOfRange(decrypted, 0, 32), Arrays.copyOfRange(decrypted, 32, 64)); + MasterPrivateExtendedKey mpek = new MasterPrivateExtendedKey(Arrays.copyOfRange(decrypted, 0, 32), Arrays.copyOfRange(decrypted, 32, 64)); + mpek.setId(getId()); + return mpek; } finally { Arrays.fill(decrypted, (byte)0); } From 729c3a1435ccf3f47db456a04c964cacd853a770 Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Wed, 16 Jun 2021 09:37:05 +0200 Subject: [PATCH 038/155] ensure deep copy of child wallets --- src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java index 1254bbe..2ccb848 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java @@ -1139,7 +1139,11 @@ public class Wallet extends Persistable { Wallet copy = new Wallet(name); copy.setId(getId()); copy.setMasterWallet(masterWallet); - copy.setChildWallets(childWallets); + for(Wallet childWallet : childWallets) { + Wallet copyChildWallet = childWallet.copy(); + copyChildWallet.setMasterWallet(copy); + copy.childWallets.add(copyChildWallet); + } copy.setPolicyType(policyType); copy.setScriptType(scriptType); copy.setDefaultPolicy(defaultPolicy.copy()); From 5e8a14678d264dfc5e30cc594f60a6f7f87292ef Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Wed, 16 Jun 2021 14:45:36 +0200 Subject: [PATCH 039/155] add seedsigner wallet model --- src/main/java/com/sparrowwallet/drongo/wallet/WalletModel.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/WalletModel.java b/src/main/java/com/sparrowwallet/drongo/wallet/WalletModel.java index 5579e6e..d01c10c 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/WalletModel.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/WalletModel.java @@ -1,7 +1,7 @@ package com.sparrowwallet.drongo.wallet; public enum WalletModel { - SEED, SPARROW, BITCOIN_CORE, ELECTRUM, TREZOR_1, TREZOR_T, COLDCARD, LEDGER_NANO_S, LEDGER_NANO_X, DIGITALBITBOX_01, KEEPKEY, SPECTER_DESKTOP, COBO_VAULT, BITBOX_02, SPECTER_DIY, PASSPORT, BLUE_WALLET, KEYSTONE; + SEED, SPARROW, BITCOIN_CORE, ELECTRUM, TREZOR_1, TREZOR_T, COLDCARD, LEDGER_NANO_S, LEDGER_NANO_X, DIGITALBITBOX_01, KEEPKEY, SPECTER_DESKTOP, COBO_VAULT, BITBOX_02, SPECTER_DIY, PASSPORT, BLUE_WALLET, KEYSTONE, SEEDSIGNER; public static WalletModel getModel(String model) { return valueOf(model.toUpperCase()); From c02130079782cc10dc47f933274f12d08c497c19 Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Fri, 18 Jun 2021 11:19:24 +0200 Subject: [PATCH 040/155] parse bitcoin core wallet model type --- .../java/com/sparrowwallet/drongo/wallet/WalletModel.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/WalletModel.java b/src/main/java/com/sparrowwallet/drongo/wallet/WalletModel.java index d01c10c..708ec92 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/WalletModel.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/WalletModel.java @@ -20,6 +20,10 @@ public enum WalletModel { return "digitalbitbox"; } + if(this == BITCOIN_CORE) { + return "bitcoincore"; + } + if(this == BITBOX_02) { return "bitbox02"; } From 9d3c02d18440b82cb261a89f372da72dd0f87a1f Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Fri, 25 Jun 2021 14:55:48 +0200 Subject: [PATCH 041/155] upgrade to gradle 7.1, java 16, javafx 16 --- build.gradle | 44 +++-- buildSrc/build.gradle | 21 +++ .../javamodules/ExtraModuleInfoPlugin.java | 54 ++++++ .../ExtraModuleInfoPluginExtension.java | 52 ++++++ .../javamodules/ExtraModuleInfoTransform.java | 164 ++++++++++++++++++ .../transform/javamodules/ModuleInfo.java | 53 ++++++ gradle/wrapper/gradle-wrapper.jar | Bin 58694 -> 59203 bytes gradle/wrapper/gradle-wrapper.properties | 2 +- gradlew | 2 + gradlew.bat | 22 +-- 10 files changed, 381 insertions(+), 33 deletions(-) create mode 100644 buildSrc/build.gradle create mode 100644 buildSrc/src/main/java/org/gradle/sample/transform/javamodules/ExtraModuleInfoPlugin.java create mode 100644 buildSrc/src/main/java/org/gradle/sample/transform/javamodules/ExtraModuleInfoPluginExtension.java create mode 100644 buildSrc/src/main/java/org/gradle/sample/transform/javamodules/ExtraModuleInfoTransform.java create mode 100644 buildSrc/src/main/java/org/gradle/sample/transform/javamodules/ModuleInfo.java diff --git a/build.gradle b/build.gradle index d6be80e..822478c 100644 --- a/build.gradle +++ b/build.gradle @@ -4,25 +4,14 @@ buildscript { url "https://plugins.gradle.org/m2/" } } - dependencies { - classpath "org.javamodularity:moduleplugin:1.6.0" - } } plugins { - id 'java' + id 'java-library' + id 'extra-java-module-info' id 'com.github.johnrengelman.shadow' version '5.2.0' } -def javamodularityPluginId = 'org.javamodularity.moduleplugin' -final hasPlugin = project.getPlugins().hasPlugin(javamodularityPluginId); -if(hasPlugin) { - final Plugin plugin = project.getPlugins().getPlugin(javamodularityPluginId) - println 'Plugin already applied - version ' + plugin.properties['javamodularityPluginId'] -} else { - apply plugin: "org.javamodularity.moduleplugin" -} - tasks.withType(AbstractArchiveTask) { preserveFileTimestamps = false reproducibleFileOrder = true @@ -65,7 +54,7 @@ dependencies { } task(runDrongo, dependsOn: 'classes', type: JavaExec) { - main = 'com.sparrowwallet.drongo.Main' + mainClass = 'com.sparrowwallet.drongo.Main' classpath = sourceSets.main.runtimeClasspath args 'drongo.properties' } @@ -85,3 +74,30 @@ shadowJar { archiveVersion = '0.9' classifier = 'all' } + +extraJavaModuleInfo { + module('logback-core-1.2.3.jar', 'logback.core', '1.2.3') { + exports('ch.qos.logback.core') + exports('ch.qos.logback.core.spi') + requires('java.xml') + } + module('logback-classic-1.2.3.jar', 'logback.classic', '1.2.3') { + exports('ch.qos.logback.classic') + exports('ch.qos.logback.classic.spi') + requires('org.slf4j') + requires('logback.core') + requires('java.xml') + requires('java.logging') + } + module('jeromq-0.5.0.jar', 'jeromq', '0.5.0') { + exports('org.zeromq') + } + module('json-simple-1.1.1.jar', 'json.simple', '1.1.1') { + exports('org.json.simple') + exports('org.json.simple.parser') + } + module('jnacl-1.0.0.jar', 'eu.neilalexander.jnacl', '1.0.0') + module('junit-4.12.jar', 'junit', '4.12') { + exports('org.junit') + } +} diff --git a/buildSrc/build.gradle b/buildSrc/build.gradle new file mode 100644 index 0000000..ebb5470 --- /dev/null +++ b/buildSrc/build.gradle @@ -0,0 +1,21 @@ +plugins { + id 'java-gradle-plugin' // so we can assign and ID to our plugin +} + +dependencies { + implementation 'org.ow2.asm:asm:8.0.1' +} + +repositories { + mavenCentral() +} + +gradlePlugin { + plugins { + // here we register our plugin with an ID + register("extra-java-module-info") { + id = "extra-java-module-info" + implementationClass = "org.gradle.sample.transform.javamodules.ExtraModuleInfoPlugin" + } + } +} diff --git a/buildSrc/src/main/java/org/gradle/sample/transform/javamodules/ExtraModuleInfoPlugin.java b/buildSrc/src/main/java/org/gradle/sample/transform/javamodules/ExtraModuleInfoPlugin.java new file mode 100644 index 0000000..48d0b0b --- /dev/null +++ b/buildSrc/src/main/java/org/gradle/sample/transform/javamodules/ExtraModuleInfoPlugin.java @@ -0,0 +1,54 @@ +package org.gradle.sample.transform.javamodules; + +import org.gradle.api.Plugin; +import org.gradle.api.Project; +import org.gradle.api.artifacts.Configuration; +import org.gradle.api.attributes.Attribute; +import org.gradle.api.plugins.JavaPlugin; + +/** + * Entry point of our plugin that should be applied in the root project. + */ +public class ExtraModuleInfoPlugin implements Plugin { + + @Override + public void apply(Project project) { + // register the plugin extension as 'extraJavaModuleInfo {}' configuration block + ExtraModuleInfoPluginExtension extension = project.getObjects().newInstance(ExtraModuleInfoPluginExtension.class); + project.getExtensions().add(ExtraModuleInfoPluginExtension.class, "extraJavaModuleInfo", extension); + + // setup the transform for all projects in the build + project.getPlugins().withType(JavaPlugin.class).configureEach(javaPlugin -> configureTransform(project, extension)); + } + + private void configureTransform(Project project, ExtraModuleInfoPluginExtension extension) { + Attribute artifactType = Attribute.of("artifactType", String.class); + Attribute javaModule = Attribute.of("javaModule", Boolean.class); + + // compile and runtime classpath express that they only accept modules by requesting the javaModule=true attribute + project.getConfigurations().matching(this::isResolvingJavaPluginConfiguration).all( + c -> c.getAttributes().attribute(javaModule, true)); + + // all Jars have a javaModule=false attribute by default; the transform also recognizes modules and returns them without modification + project.getDependencies().getArtifactTypes().getByName("jar").getAttributes().attribute(javaModule, false); + + // register the transform for Jars and "javaModule=false -> javaModule=true"; the plugin extension object fills the input parameter + project.getDependencies().registerTransform(ExtraModuleInfoTransform.class, t -> { + t.parameters(p -> { + p.setModuleInfo(extension.getModuleInfo()); + p.setAutomaticModules(extension.getAutomaticModules()); + }); + t.getFrom().attribute(artifactType, "jar").attribute(javaModule, false); + t.getTo().attribute(artifactType, "jar").attribute(javaModule, true); + }); + } + + private boolean isResolvingJavaPluginConfiguration(Configuration configuration) { + if (!configuration.isCanBeResolved()) { + return false; + } + return configuration.getName().endsWith(JavaPlugin.COMPILE_CLASSPATH_CONFIGURATION_NAME.substring(1)) + || configuration.getName().endsWith(JavaPlugin.RUNTIME_CLASSPATH_CONFIGURATION_NAME.substring(1)) + || configuration.getName().endsWith(JavaPlugin.ANNOTATION_PROCESSOR_CONFIGURATION_NAME.substring(1)); + } +} diff --git a/buildSrc/src/main/java/org/gradle/sample/transform/javamodules/ExtraModuleInfoPluginExtension.java b/buildSrc/src/main/java/org/gradle/sample/transform/javamodules/ExtraModuleInfoPluginExtension.java new file mode 100644 index 0000000..d0d4e0f --- /dev/null +++ b/buildSrc/src/main/java/org/gradle/sample/transform/javamodules/ExtraModuleInfoPluginExtension.java @@ -0,0 +1,52 @@ +package org.gradle.sample.transform.javamodules; + + +import org.gradle.api.Action; + +import javax.annotation.Nullable; +import java.util.HashMap; +import java.util.Map; + +/** + * A data class to collect all the module information we want to add. + * Here the class is used as extension that can be configured in the build script + * and as input to the ExtraModuleInfoTransform that add the information to Jars. + */ +public class ExtraModuleInfoPluginExtension { + + private final Map moduleInfo = new HashMap<>(); + private final Map automaticModules = new HashMap<>(); + + /** + * Add full module information for a given Jar file. + */ + public void module(String jarName, String moduleName, String moduleVersion) { + module(jarName, moduleName, moduleVersion, null); + } + + /** + * Add full module information, including exported packages and dependencies, for a given Jar file. + */ + public void module(String jarName, String moduleName, String moduleVersion, @Nullable Action conf) { + ModuleInfo moduleInfo = new ModuleInfo(moduleName, moduleVersion); + if (conf != null) { + conf.execute(moduleInfo); + } + this.moduleInfo.put(jarName, moduleInfo); + } + + /** + * Add only an automatic module name to a given jar file. + */ + public void automaticModule(String jarName, String moduleName) { + automaticModules.put(jarName, moduleName); + } + + protected Map getModuleInfo() { + return moduleInfo; + } + + protected Map getAutomaticModules() { + return automaticModules; + } +} diff --git a/buildSrc/src/main/java/org/gradle/sample/transform/javamodules/ExtraModuleInfoTransform.java b/buildSrc/src/main/java/org/gradle/sample/transform/javamodules/ExtraModuleInfoTransform.java new file mode 100644 index 0000000..94e6922 --- /dev/null +++ b/buildSrc/src/main/java/org/gradle/sample/transform/javamodules/ExtraModuleInfoTransform.java @@ -0,0 +1,164 @@ +package org.gradle.sample.transform.javamodules; + +import org.gradle.api.artifacts.transform.InputArtifact; +import org.gradle.api.artifacts.transform.TransformAction; +import org.gradle.api.artifacts.transform.TransformOutputs; +import org.gradle.api.artifacts.transform.TransformParameters; +import org.gradle.api.file.FileSystemLocation; +import org.gradle.api.provider.Provider; +import org.gradle.api.tasks.Input; +import org.objectweb.asm.ClassWriter; +import org.objectweb.asm.ModuleVisitor; +import org.objectweb.asm.Opcodes; + +import java.io.*; +import java.util.Collections; +import java.util.Map; +import java.util.jar.*; +import java.util.regex.Pattern; +import java.util.zip.ZipEntry; + +/** + * An artifact transform that applies additional information to Jars without module information. + * The transformation fails the build if a Jar does not contain information and no extra information + * was defined for it. This way we make sure that all Jars are turned into modules. + */ +abstract public class ExtraModuleInfoTransform implements TransformAction { + + public static class Parameter implements TransformParameters, Serializable { + private Map moduleInfo = Collections.emptyMap(); + private Map automaticModules = Collections.emptyMap(); + + @Input + public Map getModuleInfo() { + return moduleInfo; + } + + @Input + public Map getAutomaticModules() { + return automaticModules; + } + + public void setModuleInfo(Map moduleInfo) { + this.moduleInfo = moduleInfo; + } + + public void setAutomaticModules(Map automaticModules) { + this.automaticModules = automaticModules; + } + } + + @InputArtifact + protected abstract Provider getInputArtifact(); + + @Override + public void transform(TransformOutputs outputs) { + Map moduleInfo = getParameters().moduleInfo; + Map automaticModules = getParameters().automaticModules; + File originalJar = getInputArtifact().get().getAsFile(); + String originalJarName = originalJar.getName(); + + if (isModule(originalJar)) { + outputs.file(originalJar); + } else if (moduleInfo.containsKey(originalJarName)) { + addModuleDescriptor(originalJar, getModuleJar(outputs, originalJar), moduleInfo.get(originalJarName)); + } else if (isAutoModule(originalJar)) { + outputs.file(originalJar); + } else if (automaticModules.containsKey(originalJarName)) { + addAutomaticModuleName(originalJar, getModuleJar(outputs, originalJar), automaticModules.get(originalJarName)); + } else { + throw new RuntimeException("Not a module and no mapping defined: " + originalJarName); + } + } + + private boolean isModule(File jar) { + Pattern moduleInfoClassMrjarPath = Pattern.compile("META-INF/versions/\\d+/module-info.class"); + try (JarInputStream inputStream = new JarInputStream(new FileInputStream(jar))) { + boolean isMultiReleaseJar = containsMultiReleaseJarEntry(inputStream); + ZipEntry next = inputStream.getNextEntry(); + while (next != null) { + if ("module-info.class".equals(next.getName())) { + return true; + } + if (isMultiReleaseJar && moduleInfoClassMrjarPath.matcher(next.getName()).matches()) { + return true; + } + next = inputStream.getNextEntry(); + } + } catch (IOException e) { + throw new RuntimeException(e); + } + return false; + } + + private boolean containsMultiReleaseJarEntry(JarInputStream jarStream) { + Manifest manifest = jarStream.getManifest(); + return manifest != null && Boolean.parseBoolean(manifest.getMainAttributes().getValue("Multi-Release")); + } + + private boolean isAutoModule(File jar) { + try (JarInputStream inputStream = new JarInputStream(new FileInputStream(jar))) { + return inputStream.getManifest().getMainAttributes().getValue("Automatic-Module-Name") != null; + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + private File getModuleJar(TransformOutputs outputs, File originalJar) { + return outputs.file(originalJar.getName().substring(0, originalJar.getName().lastIndexOf('.')) + "-module.jar"); + } + + private static void addAutomaticModuleName(File originalJar, File moduleJar, String moduleName) { + try (JarInputStream inputStream = new JarInputStream(new FileInputStream(originalJar))) { + Manifest manifest = inputStream.getManifest(); + manifest.getMainAttributes().put(new Attributes.Name("Automatic-Module-Name"), moduleName); + try (JarOutputStream outputStream = new JarOutputStream(new FileOutputStream(moduleJar), inputStream.getManifest())) { + copyEntries(inputStream, outputStream); + } + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + private static void addModuleDescriptor(File originalJar, File moduleJar, ModuleInfo moduleInfo) { + try (JarInputStream inputStream = new JarInputStream(new FileInputStream(originalJar))) { + try (JarOutputStream outputStream = new JarOutputStream(new FileOutputStream(moduleJar), inputStream.getManifest())) { + copyEntries(inputStream, outputStream); + outputStream.putNextEntry(new JarEntry("module-info.class")); + outputStream.write(addModuleInfo(moduleInfo)); + outputStream.closeEntry(); + } + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + private static void copyEntries(JarInputStream inputStream, JarOutputStream outputStream) throws IOException { + JarEntry jarEntry = inputStream.getNextJarEntry(); + while (jarEntry != null) { + outputStream.putNextEntry(jarEntry); + outputStream.write(inputStream.readAllBytes()); + outputStream.closeEntry(); + jarEntry = inputStream.getNextJarEntry(); + } + } + + private static byte[] addModuleInfo(ModuleInfo moduleInfo) { + ClassWriter classWriter = new ClassWriter(0); + classWriter.visit(Opcodes.V9, Opcodes.ACC_MODULE, "module-info", null, null, null); + ModuleVisitor moduleVisitor = classWriter.visitModule(moduleInfo.getModuleName(), Opcodes.ACC_OPEN, moduleInfo.getModuleVersion()); + for (String packageName : moduleInfo.getExports()) { + moduleVisitor.visitExport(packageName.replace('.', '/'), 0); + } + moduleVisitor.visitRequire("java.base", 0, null); + for (String requireName : moduleInfo.getRequires()) { + moduleVisitor.visitRequire(requireName, 0, null); + } + for (String requireName : moduleInfo.getRequiresTransitive()) { + moduleVisitor.visitRequire(requireName, Opcodes.ACC_TRANSITIVE, null); + } + moduleVisitor.visitEnd(); + classWriter.visitEnd(); + return classWriter.toByteArray(); + } +} diff --git a/buildSrc/src/main/java/org/gradle/sample/transform/javamodules/ModuleInfo.java b/buildSrc/src/main/java/org/gradle/sample/transform/javamodules/ModuleInfo.java new file mode 100644 index 0000000..9884a91 --- /dev/null +++ b/buildSrc/src/main/java/org/gradle/sample/transform/javamodules/ModuleInfo.java @@ -0,0 +1,53 @@ +package org.gradle.sample.transform.javamodules; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; + +/** + * Data class to hold the information that should be added as module-info.class to an existing Jar file. + */ +public class ModuleInfo implements Serializable { + private String moduleName; + private String moduleVersion; + private List exports = new ArrayList<>(); + private List requires = new ArrayList<>(); + private List requiresTransitive = new ArrayList<>(); + + ModuleInfo(String moduleName, String moduleVersion) { + this.moduleName = moduleName; + this.moduleVersion = moduleVersion; + } + + public void exports(String exports) { + this.exports.add(exports); + } + + public void requires(String requires) { + this.requires.add(requires); + } + + public void requiresTransitive(String requiresTransitive) { + this.requiresTransitive.add(requiresTransitive); + } + + public String getModuleName() { + return moduleName; + } + + protected String getModuleVersion() { + return moduleVersion; + } + + protected List getExports() { + return exports; + } + + protected List getRequires() { + return requires; + } + + protected List getRequiresTransitive() { + return requiresTransitive; + } +} diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 490fda8577df6c95960ba7077c43220e5bb2c0d9..e708b1c023ec8b20f512888fe07c5bd3ff77bb8f 100644 GIT binary patch delta 6763 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 2>&1 -if "%ERRORLEVEL%" == "0" goto init +if "%ERRORLEVEL%" == "0" goto execute echo. echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. @@ -54,7 +54,7 @@ goto fail set JAVA_HOME=%JAVA_HOME:"=% set JAVA_EXE=%JAVA_HOME%/bin/java.exe -if exist "%JAVA_EXE%" goto init +if exist "%JAVA_EXE%" goto execute echo. echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% @@ -64,28 +64,14 @@ echo location of your Java installation. goto fail -:init -@rem Get command-line arguments, handling Windows variants - -if not "%OS%" == "Windows_NT" goto win9xME_args - -:win9xME_args -@rem Slurp the command line arguments. -set CMD_LINE_ARGS= -set _SKIP=2 - -:win9xME_args_slurp -if "x%~1" == "x" goto execute - -set CMD_LINE_ARGS=%* - :execute @rem Setup the command line set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* :end @rem End local scope for the variables with windows NT shell From 107a165fc1db84f80febbe358aaab16b2764a5d5 Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Mon, 28 Jun 2021 13:08:09 +0200 Subject: [PATCH 042/155] support determining if tx input refers to a txo from a wallet --- .../drongo/wallet/FinalizingPSBTWallet.java | 17 +++++++++++++---- .../com/sparrowwallet/drongo/wallet/Wallet.java | 4 ++++ 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/FinalizingPSBTWallet.java b/src/main/java/com/sparrowwallet/drongo/wallet/FinalizingPSBTWallet.java index 360836e..5a4dff7 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/FinalizingPSBTWallet.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/FinalizingPSBTWallet.java @@ -5,10 +5,7 @@ import com.sparrowwallet.drongo.crypto.ECKey; import com.sparrowwallet.drongo.policy.Miniscript; import com.sparrowwallet.drongo.policy.Policy; import com.sparrowwallet.drongo.policy.PolicyType; -import com.sparrowwallet.drongo.protocol.NonStandardScriptException; -import com.sparrowwallet.drongo.protocol.Script; -import com.sparrowwallet.drongo.protocol.ScriptType; -import com.sparrowwallet.drongo.protocol.TransactionSignature; +import com.sparrowwallet.drongo.protocol.*; import com.sparrowwallet.drongo.psbt.PSBT; import com.sparrowwallet.drongo.psbt.PSBTInput; @@ -125,4 +122,16 @@ public class FinalizingPSBTWallet extends Wallet { public boolean canSign(PSBT psbt) { return !getSigningNodes(psbt).isEmpty(); } + + @Override + public boolean isWalletTxo(TransactionInput txInput) { + for(PSBTInput psbtInput : signedInputNodes.keySet()) { + TransactionInput psbtTxInput = psbtInput.getInput(); + if(psbtTxInput.getOutpoint().getHash().equals(txInput.getOutpoint().getHash()) && psbtTxInput.getOutpoint().getIndex() == txInput.getOutpoint().getIndex()) { + return true; + } + } + + return false; + } } \ No newline at end of file diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java index 2ccb848..6deee5b 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java @@ -351,6 +351,10 @@ public class Wallet extends Persistable { } } + public boolean isWalletTxo(TransactionInput txInput) { + return getWalletTxos().keySet().stream().anyMatch(ref -> ref.getHash().equals(txInput.getOutpoint().getHash()) && ref.getIndex() == txInput.getOutpoint().getIndex()); + } + public boolean isWalletTxo(BlockTransactionHashIndex txo) { return getWalletTxos().containsKey(txo); } From 967a2c2026f15a6b458d055e33ac488e53df65fd Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Fri, 2 Jul 2021 10:43:26 +0200 Subject: [PATCH 043/155] add support for sending to taproot addresses --- .../sparrowwallet/drongo/address/Address.java | 20 +++- .../drongo/address/P2PKAddress.java | 2 +- .../drongo/address/P2TRAddress.java | 46 ++++++++ .../sparrowwallet/drongo/crypto/ECKey.java | 13 +- .../drongo/crypto/LazyECPoint.java | 16 ++- .../sparrowwallet/drongo/protocol/Bech32.java | 55 +++++++-- .../sparrowwallet/drongo/protocol/Script.java | 21 +++- .../drongo/protocol/ScriptType.java | 111 +++++++++++++++++- .../sparrowwallet/drongo/wallet/Wallet.java | 2 +- .../drongo/address/AddressTest.java | 17 +++ 10 files changed, 279 insertions(+), 24 deletions(-) create mode 100644 src/main/java/com/sparrowwallet/drongo/address/P2TRAddress.java diff --git a/src/main/java/com/sparrowwallet/drongo/address/Address.java b/src/main/java/com/sparrowwallet/drongo/address/Address.java index 90bf9ca..e557ada 100644 --- a/src/main/java/com/sparrowwallet/drongo/address/Address.java +++ b/src/main/java/com/sparrowwallet/drongo/address/Address.java @@ -108,15 +108,29 @@ public abstract class Address { Bech32.Bech32Data data = Bech32.decode(address); if(data.hrp.equals(network.getBech32AddressHRP())) { int witnessVersion = data.data[0]; - if (witnessVersion == 0) { + if(witnessVersion == 0) { + if(data.encoding != Bech32.Encoding.BECH32) { + throw new InvalidAddressException("Invalid address - witness version is 0 but encoding is " + data.encoding); + } + byte[] convertedProgram = Arrays.copyOfRange(data.data, 1, data.data.length); byte[] witnessProgram = Bech32.convertBits(convertedProgram, 0, convertedProgram.length, 5, 8, false); - if (witnessProgram.length == 20) { + if(witnessProgram.length == 20) { return new P2WPKHAddress(witnessProgram); } - if (witnessProgram.length == 32) { + if(witnessProgram.length == 32) { return new P2WSHAddress(witnessProgram); } + } else if(witnessVersion == 1) { + if(data.encoding != Bech32.Encoding.BECH32M) { + throw new InvalidAddressException("Invalid address - witness version is 1 but encoding is " + data.encoding); + } + + byte[] convertedProgram = Arrays.copyOfRange(data.data, 1, data.data.length); + byte[] witnessProgram = Bech32.convertBits(convertedProgram, 0, convertedProgram.length, 5, 8, false); + if(witnessProgram.length == 32) { + return new P2TRAddress(witnessProgram); + } } } } catch (Exception e) { diff --git a/src/main/java/com/sparrowwallet/drongo/address/P2PKAddress.java b/src/main/java/com/sparrowwallet/drongo/address/P2PKAddress.java index 35df236..aaa956b 100644 --- a/src/main/java/com/sparrowwallet/drongo/address/P2PKAddress.java +++ b/src/main/java/com/sparrowwallet/drongo/address/P2PKAddress.java @@ -6,7 +6,7 @@ import com.sparrowwallet.drongo.protocol.Script; import com.sparrowwallet.drongo.protocol.ScriptType; public class P2PKAddress extends Address { - private byte[] pubKey; + private final byte[] pubKey; public P2PKAddress(byte[] pubKey) { super(Utils.sha256hash160(pubKey)); diff --git a/src/main/java/com/sparrowwallet/drongo/address/P2TRAddress.java b/src/main/java/com/sparrowwallet/drongo/address/P2TRAddress.java new file mode 100644 index 0000000..a263762 --- /dev/null +++ b/src/main/java/com/sparrowwallet/drongo/address/P2TRAddress.java @@ -0,0 +1,46 @@ +package com.sparrowwallet.drongo.address; + +import com.sparrowwallet.drongo.Network; +import com.sparrowwallet.drongo.Utils; +import com.sparrowwallet.drongo.protocol.Bech32; +import com.sparrowwallet.drongo.protocol.Script; +import com.sparrowwallet.drongo.protocol.ScriptType; + +public class P2TRAddress extends Address { + private final byte[] pubKey; + + public P2TRAddress(byte[] pubKey) { + super(Utils.sha256hash160(pubKey)); + this.pubKey = pubKey; + } + + @Override + public int getVersion(Network network) { + return 1; + } + + @Override + public String getAddress(Network network) { + return Bech32.encode(network.getBech32AddressHRP(), getVersion(), pubKey); + } + + @Override + public ScriptType getScriptType() { + return ScriptType.P2TR; + } + + @Override + public Script getOutputScript() { + return getScriptType().getOutputScript(pubKey); + } + + @Override + public byte[] getOutputScriptData() { + return pubKey; + } + + @Override + public String getOutputScriptDataType() { + return "Taproot"; + } +} diff --git a/src/main/java/com/sparrowwallet/drongo/crypto/ECKey.java b/src/main/java/com/sparrowwallet/drongo/crypto/ECKey.java index 1075ef3..d62f852 100644 --- a/src/main/java/com/sparrowwallet/drongo/crypto/ECKey.java +++ b/src/main/java/com/sparrowwallet/drongo/crypto/ECKey.java @@ -340,6 +340,13 @@ public class ECKey implements EncryptableItem { return pub.getEncoded(); } + /** + * Gets the x coordinate of the raw public key value. This appears in transaction scriptPubKeys for Taproot outputs. + */ + public byte[] getPubKeyXCoord() { + return pub.getEncodedXCoord(); + } + /** Gets the public key in the form of an elliptic curve point object from Bouncy Castle. */ public ECPoint getPubKeyPoint() { return pub.get(); @@ -625,8 +632,10 @@ public class ECKey implements EncryptableItem { * Returns true if the given pubkey is canonical, i.e. the correct length taking into account compression. */ public static boolean isPubKeyCanonical(byte[] pubkey) { - if (pubkey.length < 33) + if (pubkey.length < 32) return false; + if (pubkey.length == 32) + return true; if (pubkey[0] == 0x04) { // Uncompressed pubkey if (pubkey.length != 65) @@ -644,7 +653,7 @@ public class ECKey implements EncryptableItem { * Returns true if the given pubkey is in its compressed form. */ public static boolean isPubKeyCompressed(byte[] encoded) { - if (encoded.length == 33 && (encoded[0] == 0x02 || encoded[0] == 0x03)) + if (encoded.length == 32 || (encoded.length == 33 && (encoded[0] == 0x02 || encoded[0] == 0x03))) return true; else if (encoded.length == 65 && encoded[0] == 0x04) return false; diff --git a/src/main/java/com/sparrowwallet/drongo/crypto/LazyECPoint.java b/src/main/java/com/sparrowwallet/drongo/crypto/LazyECPoint.java index 981f935..1eee6bc 100644 --- a/src/main/java/com/sparrowwallet/drongo/crypto/LazyECPoint.java +++ b/src/main/java/com/sparrowwallet/drongo/crypto/LazyECPoint.java @@ -20,7 +20,7 @@ public class LazyECPoint { public LazyECPoint(ECCurve curve, byte[] bits) { this.curve = curve; - this.bits = bits; + this.bits = (bits != null && bits.length == 32 ? addYCoord(bits) : bits); this.compressed = ECKey.isPubKeyCompressed(bits); } @@ -61,6 +61,13 @@ public class LazyECPoint { return get().getEncoded(compressed); } + public byte[] getEncodedXCoord() { + byte[] compressed = getEncoded(true); + byte[] xcoord = new byte[32]; + System.arraycopy(compressed, 1, xcoord, 0, 32); + return xcoord; + } + public String toString() { return Hex.toHexString(getEncoded()); } @@ -80,4 +87,11 @@ public class LazyECPoint { private byte[] getCanonicalEncoding() { return getEncoded(true); } + + private static byte[] addYCoord(byte[] xcoord) { + byte[] compressed = new byte[33]; + compressed[0] = 0x02; + System.arraycopy(xcoord, 0, compressed, 1, 32); + return compressed; + } } diff --git a/src/main/java/com/sparrowwallet/drongo/protocol/Bech32.java b/src/main/java/com/sparrowwallet/drongo/protocol/Bech32.java index da5ad0a..7ed7f16 100644 --- a/src/main/java/com/sparrowwallet/drongo/protocol/Bech32.java +++ b/src/main/java/com/sparrowwallet/drongo/protocol/Bech32.java @@ -39,10 +39,18 @@ public class Bech32 { public static class Bech32Data { public final String hrp; public final byte[] data; + public final Encoding encoding; private Bech32Data(final String hrp, final byte[] data) { this.hrp = hrp; this.data = data; + this.encoding = (data[0] == 0x00 ? Encoding.BECH32 : Encoding.BECH32M); + } + + public Bech32Data(String hrp, byte[] data, Encoding encoding) { + this.hrp = hrp; + this.data = data; + this.encoding = encoding; } } @@ -64,7 +72,7 @@ public class Bech32 { /** Expand a HRP for use in checksum computation. */ private static byte[] expandHrp(final String hrp) { int hrpLength = hrp.length(); - byte ret[] = new byte[hrpLength * 2 + 1]; + byte[] ret = new byte[hrpLength * 2 + 1]; for (int i = 0; i < hrpLength; ++i) { int c = hrp.charAt(i) & 0x7f; // Limit to standard 7-bit ASCII ret[i] = (byte) ((c >>> 5) & 0x07); @@ -75,21 +83,29 @@ public class Bech32 { } /** Verify a checksum. */ - private static boolean verifyChecksum(final String hrp, final byte[] values) { + private static Encoding verifyChecksum(final String hrp, final byte[] values) { byte[] hrpExpanded = expandHrp(hrp); byte[] combined = new byte[hrpExpanded.length + values.length]; System.arraycopy(hrpExpanded, 0, combined, 0, hrpExpanded.length); System.arraycopy(values, 0, combined, hrpExpanded.length, values.length); - return polymod(combined) == 1; + + int check = polymod(combined); + for(Encoding encoding : Encoding.values()) { + if(check == encoding.checksumConstant) { + return encoding; + } + } + + return null; } /** Create a checksum. */ - private static byte[] createChecksum(final String hrp, final byte[] values) { + private static byte[] createChecksum(final String hrp, Encoding encoding, final byte[] values) { byte[] hrpExpanded = expandHrp(hrp); byte[] enc = new byte[hrpExpanded.length + values.length + 6]; System.arraycopy(hrpExpanded, 0, enc, 0, hrpExpanded.length); System.arraycopy(values, 0, enc, hrpExpanded.length, values.length); - int mod = polymod(enc) ^ 1; + int mod = polymod(enc) ^ encoding.checksumConstant; byte[] ret = new byte[6]; for (int i = 0; i < 6; ++i) { ret[i] = (byte) ((mod >>> (5 * (5 - i))) & 31); @@ -99,16 +115,17 @@ public class Bech32 { /** Encode a Bech32 string. */ public static String encode(final Bech32Data bech32) { - return encode(bech32.hrp, bech32.data); + return encode(bech32.hrp, bech32.encoding, bech32.data); } /** Encode a Bech32 string. */ public static String encode(String hrp, int version, final byte[] values) { - return encode(hrp, encode(0, values)); + Encoding encoding = (version == 0 ? Encoding.BECH32 : Encoding.BECH32M); + return encode(hrp, encoding, encode(version, values)); } /** Encode a Bech32 string. */ - public static String encode(String hrp, final byte[] values) { + public static String encode(String hrp, Encoding encoding, final byte[] values) { if(hrp.length() < 1) { throw new ProtocolException("Human-readable part is too short"); } @@ -118,7 +135,7 @@ public class Bech32 { } hrp = hrp.toLowerCase(Locale.ROOT); - byte[] checksum = createChecksum(hrp, values); + byte[] checksum = createChecksum(hrp, encoding, values); byte[] combined = new byte[values.length + checksum.length]; System.arraycopy(values, 0, combined, 0, values.length); System.arraycopy(checksum, 0, combined, values.length, checksum.length); @@ -163,14 +180,18 @@ public class Bech32 { values[i] = CHARSET_REV[c]; } String hrp = str.substring(0, pos).toLowerCase(Locale.ROOT); - if (!verifyChecksum(hrp, values)) throw new ProtocolException("Invalid checksum"); - return new Bech32Data(hrp, Arrays.copyOfRange(values, 0, values.length - 6)); + Encoding encoding = verifyChecksum(hrp, values); + if(encoding == null) { + throw new ProtocolException("Invalid checksum"); + } + + return new Bech32Data(hrp, Arrays.copyOfRange(values, 0, values.length - 6), encoding); } private static byte[] encode(int witnessVersion, byte[] witnessProgram) { byte[] convertedProgram = convertBits(witnessProgram, 0, witnessProgram.length, 8, 5, true); byte[] bytes = new byte[1 + convertedProgram.length]; - bytes[0] = (byte) (Script.encodeToOpN(witnessVersion) & 0xff); + bytes[0] = (byte)(witnessVersion & 0xff); System.arraycopy(convertedProgram, 0, bytes, 1, convertedProgram.length); return bytes; } @@ -206,4 +227,14 @@ public class Bech32 { } return out.toByteArray(); } + + public enum Encoding { + BECH32(1), BECH32M(0x2bc830a3); + + private final int checksumConstant; + + Encoding(int checksumConstant) { + this.checksumConstant = checksumConstant; + } + } } diff --git a/src/main/java/com/sparrowwallet/drongo/protocol/Script.java b/src/main/java/com/sparrowwallet/drongo/protocol/Script.java index 05435f4..36f5d41 100644 --- a/src/main/java/com/sparrowwallet/drongo/protocol/Script.java +++ b/src/main/java/com/sparrowwallet/drongo/protocol/Script.java @@ -135,6 +135,21 @@ public class Script { return false; } + /** + *

If the program somehow pays to a pubkey, returns the pubkey.

+ * + *

Otherwise this method throws a ScriptException.

+ */ + public ECKey getPubKey() throws ProtocolException { + for(ScriptType scriptType : SINGLE_KEY_TYPES) { + if(scriptType.isScriptType(this)) { + return scriptType.getPublicKeyFromScript(this); + } + } + + throw new ProtocolException("Script not a standard form that contains a single key"); + } + /** *

If the program somehow pays to a hash, returns the hash.

* @@ -160,8 +175,10 @@ public class Script { } } - if(P2PK.isScriptType(this)) { - return new Address[] { P2PK.getAddress(P2PK.getPublicKeyFromScript(this).getPubKey()) }; + for(ScriptType scriptType : SINGLE_KEY_TYPES) { + if(scriptType.isScriptType(this)) { + return new Address[] { scriptType.getAddress(scriptType.getPublicKeyFromScript(this)) }; + } } if(MULTISIG.isScriptType(this)) { diff --git a/src/main/java/com/sparrowwallet/drongo/protocol/ScriptType.java b/src/main/java/com/sparrowwallet/drongo/protocol/ScriptType.java index 2a0a7c0..8e07b8c 100644 --- a/src/main/java/com/sparrowwallet/drongo/protocol/ScriptType.java +++ b/src/main/java/com/sparrowwallet/drongo/protocol/ScriptType.java @@ -974,6 +974,106 @@ public enum ScriptType { public List getAllowedPolicyTypes() { return List.of(MULTI, CUSTOM); } + }, + P2TR("P2TR", "Taproot (P2TR)", "m/6789'/0'/0'") { + @Override + public Address getAddress(byte[] pubKey) { + return new P2TRAddress(pubKey); + } + + @Override + public Address getAddress(ECKey key) { + return getAddress(key.getPubKeyXCoord()); + } + + @Override + public Address getAddress(Script script) { + throw new ProtocolException("Cannot create a taproot address without a keypath"); + } + + @Override + public Script getOutputScript(byte[] pubKey) { + List chunks = new ArrayList<>(); + chunks.add(new ScriptChunk(OP_1, null)); + chunks.add(new ScriptChunk(pubKey.length, pubKey)); + + return new Script(chunks); + } + + @Override + public Script getOutputScript(ECKey key) { + return getOutputScript(key.getPubKeyXCoord()); + } + + @Override + public Script getOutputScript(Script script) { + throw new ProtocolException("Cannot create a taproot output script without a keypath"); + } + + @Override + public String getOutputDescriptor(ECKey key) { + return getDescriptor() + Utils.bytesToHex(key.getPubKeyXCoord()) + getCloseDescriptor(); + } + + @Override + public String getOutputDescriptor(Script script) { + throw new ProtocolException("Cannot create a taproot output descriptor without a keypath"); + } + + @Override + public String getDescriptor() { + return "tr("; + } + + @Override + public boolean isScriptType(Script script) { + List chunks = script.chunks; + if (chunks.size() != 2) + return false; + if (!chunks.get(0).equalsOpCode(OP_1)) + return false; + byte[] chunk1data = chunks.get(1).data; + if (chunk1data == null) + return false; + if (chunk1data.length != 32) + return false; + return true; + } + + @Override + public byte[] getHashFromScript(Script script) { + throw new ProtocolException("P2TR script does not contain a hash, use getPublicKeyFromScript(script) to retrieve public key"); + } + + @Override + public ECKey getPublicKeyFromScript(Script script) { + return ECKey.fromPublicOnly(script.chunks.get(1).data); + } + + @Override + public Script getScriptSig(Script scriptPubKey, ECKey pubKey, TransactionSignature signature) { + throw new UnsupportedOperationException("Constructing Taproot inputs is not yet supported"); + } + + @Override + public TransactionInput addSpendingInput(Transaction transaction, TransactionOutput prevOutput, ECKey pubKey, TransactionSignature signature) { + throw new UnsupportedOperationException("Constructing Taproot inputs is not yet supported"); + } + + @Override + public Script getMultisigScriptSig(Script scriptPubKey, int threshold, Map pubKeySignatures) { + throw new UnsupportedOperationException("Constructing Taproot inputs is not yet supported"); + } + + @Override + public TransactionInput addMultisigSpendingInput(Transaction transaction, TransactionOutput prevOutput, int threshold, Map pubKeySignatures) { + throw new UnsupportedOperationException("Constructing Taproot inputs is not yet supported"); + } + + @Override + public List getAllowedPolicyTypes() { + return Collections.emptyList(); + } }; private final String name; @@ -1087,18 +1187,22 @@ public enum ScriptType { public abstract TransactionInput addMultisigSpendingInput(Transaction transaction, TransactionOutput prevOutput, int threshold, Map pubKeySignatures); + public static final ScriptType[] SINGLE_KEY_TYPES = {P2PK, P2TR}; + public static final ScriptType[] SINGLE_HASH_TYPES = {P2PKH, P2SH, P2SH_P2WPKH, P2SH_P2WSH, P2WPKH, P2WSH}; + public static final ScriptType[] ADDRESSABLE_TYPES = {P2PKH, P2SH, P2SH_P2WPKH, P2SH_P2WSH, P2WPKH, P2WSH, P2TR}; + public static final ScriptType[] NON_WITNESS_TYPES = {P2PK, P2PKH, P2SH}; - public static final ScriptType[] WITNESS_TYPES = {P2SH_P2WPKH, P2SH_P2WSH, P2WPKH, P2WSH}; + public static final ScriptType[] WITNESS_TYPES = {P2SH_P2WPKH, P2SH_P2WSH, P2WPKH, P2WSH, P2TR}; public static List getScriptTypesForPolicyType(PolicyType policyType) { return Arrays.stream(values()).filter(scriptType -> scriptType.isAllowed(policyType)).collect(Collectors.toList()); } public static List getAddressableScriptTypes(PolicyType policyType) { - return Arrays.stream(values()).filter(scriptType -> scriptType.isAllowed(policyType) && Arrays.asList(SINGLE_HASH_TYPES).contains(scriptType)).collect(Collectors.toList()); + return Arrays.stream(ADDRESSABLE_TYPES).filter(scriptType -> scriptType.isAllowed(policyType)).collect(Collectors.toList()); } public static ScriptType getType(Script script) { @@ -1166,6 +1270,9 @@ public enum ScriptType { return (32 + 4 + 1 + 13 + (107 / WITNESS_SCALE_FACTOR) + 4); } else if(P2SH_P2WSH.equals(this)) { return (32 + 4 + 1 + 35 + (107 / WITNESS_SCALE_FACTOR) + 4); + } else if(P2TR.equals(this)) { + //Assume a default keypath spend + return (32 + 4 + 1 + (66 / WITNESS_SCALE_FACTOR) + 4); } else if(Arrays.asList(WITNESS_TYPES).contains(this)) { //Return length of spending input with 75% discount to script size return (32 + 4 + 1 + (107 / WITNESS_SCALE_FACTOR) + 4); diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java index 6deee5b..1d8eac9 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java @@ -443,7 +443,7 @@ public class Wallet extends Persistable { public int getNoInputsWeightUnits(List payments) { Transaction transaction = new Transaction(); if(Arrays.asList(ScriptType.WITNESS_TYPES).contains(getScriptType())) { - transaction.setSegwitVersion(0); + transaction.setSegwitVersion(1); } for(Payment payment : payments) { transaction.addOutput(payment.getAmount(), payment.getAddress()); diff --git a/src/test/java/com/sparrowwallet/drongo/address/AddressTest.java b/src/test/java/com/sparrowwallet/drongo/address/AddressTest.java index 9978803..fd4b799 100644 --- a/src/test/java/com/sparrowwallet/drongo/address/AddressTest.java +++ b/src/test/java/com/sparrowwallet/drongo/address/AddressTest.java @@ -49,6 +49,14 @@ public class AddressTest { Address address10 = Address.fromString(Network.SIGNET, "2NCZUtUt6gzXyBiPEQi5yQyrgR6f6F6Ki6A"); Assert.assertTrue(address10 instanceof P2SHAddress); Assert.assertEquals("2NCZUtUt6gzXyBiPEQi5yQyrgR6f6F6Ki6A", address10.toString(Network.SIGNET)); + + Address address11 = Address.fromString("bc1p0xlxvlhemja6c4dqv22uapctqupfhlxm9h8z3k2e72q4k9hcz7vqzk5jj0"); + Assert.assertTrue(address11 instanceof P2TRAddress); + Assert.assertEquals("bc1p0xlxvlhemja6c4dqv22uapctqupfhlxm9h8z3k2e72q4k9hcz7vqzk5jj0", address11.toString()); + + Address address12 = Address.fromString(Network.TESTNET, "tb1pqqqqp399et2xygdj5xreqhjjvcmzhxw4aywxecjdzew6hylgvsesf3hn0c"); + Assert.assertTrue(address12 instanceof P2TRAddress); + Assert.assertEquals("tb1pqqqqp399et2xygdj5xreqhjjvcmzhxw4aywxecjdzew6hylgvsesf3hn0c", address12.toString(Network.TESTNET)); } @Test @@ -74,6 +82,10 @@ public class AddressTest { Address address9 = Address.fromString("2NCZUtUt6gzXyBiPEQi5yQyrgR6f6F6Ki6A"); Assert.assertTrue(address9 instanceof P2SHAddress); Assert.assertEquals("2NCZUtUt6gzXyBiPEQi5yQyrgR6f6F6Ki6A", address9.toString()); + + Address address12 = Address.fromString("tb1pqqqqp399et2xygdj5xreqhjjvcmzhxw4aywxecjdzew6hylgvsesf3hn0c"); + Assert.assertTrue(address12 instanceof P2TRAddress); + Assert.assertEquals("tb1pqqqqp399et2xygdj5xreqhjjvcmzhxw4aywxecjdzew6hylgvsesf3hn0c", address12.toString()); } @Test @@ -119,6 +131,11 @@ public class AddressTest { Address address1 = Address.fromString("bc1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3qccfmb3"); } + @Test(expected = InvalidAddressException.class) + public void invalidEncodingAddressTest() throws InvalidAddressException { + Address address1 = Address.fromString("bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kemeawh"); + } + @After public void tearDown() throws Exception { Network.set(null); From 60511e2c83eb9a39ab4fd47749b0e7e2da7bf748 Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Fri, 2 Jul 2021 13:40:23 +0200 Subject: [PATCH 044/155] add native secp256k1 library with jni bindings --- build.gradle | 16 +- .../com/sparrowwallet/drongo/NativeUtils.java | 118 +++ src/main/java/module-info.java | 1 + .../java/org/bitcoin/NativeSecp256k1.java | 910 ++++++++++++++++++ .../java/org/bitcoin/NativeSecp256k1Util.java | 51 + .../java/org/bitcoin/Secp256k1Context.java | 55 ++ .../native/linux/x64/libsecp256k1.so | Bin 0 -> 244824 bytes .../native/osx/x64/libsecp256k1.dylib | Bin 0 -> 446176 bytes .../native/windows/x64/libsecp256k1-0.dll | Bin 0 -> 507193 bytes 9 files changed, 1150 insertions(+), 1 deletion(-) create mode 100644 src/main/java/com/sparrowwallet/drongo/NativeUtils.java create mode 100644 src/main/java/org/bitcoin/NativeSecp256k1.java create mode 100644 src/main/java/org/bitcoin/NativeSecp256k1Util.java create mode 100644 src/main/java/org/bitcoin/Secp256k1Context.java create mode 100755 src/main/resources/native/linux/x64/libsecp256k1.so create mode 100755 src/main/resources/native/osx/x64/libsecp256k1.dylib create mode 100755 src/main/resources/native/windows/x64/libsecp256k1-0.dll diff --git a/build.gradle b/build.gradle index 822478c..8781284 100644 --- a/build.gradle +++ b/build.gradle @@ -18,7 +18,13 @@ tasks.withType(AbstractArchiveTask) { } group 'com.sparrowwallet' -version '0.9' +version '1.0' + +def os = org.gradle.internal.os.OperatingSystem.current() +def osName = os.getFamilyName() +if(os.macOsX) { + osName = "osx" +} sourceCompatibility = 11 targetCompatibility = 11 @@ -53,6 +59,14 @@ dependencies { testImplementation group: 'org.hamcrest', name: 'hamcrest-core', version: '2.2' } +processResources { + doLast { + delete fileTree("$buildDir/resources/main/native").matching { + exclude "${osName}/**" + } + } +} + task(runDrongo, dependsOn: 'classes', type: JavaExec) { mainClass = 'com.sparrowwallet.drongo.Main' classpath = sourceSets.main.runtimeClasspath diff --git a/src/main/java/com/sparrowwallet/drongo/NativeUtils.java b/src/main/java/com/sparrowwallet/drongo/NativeUtils.java new file mode 100644 index 0000000..73cf725 --- /dev/null +++ b/src/main/java/com/sparrowwallet/drongo/NativeUtils.java @@ -0,0 +1,118 @@ +package com.sparrowwallet.drongo; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.*; + +/** + * A simple library class which helps with loading dynamic libraries stored in the + * JAR archive. These libraries usually contain implementation of some methods in + * native code (using JNI - Java Native Interface). + * + * @see http://adamheinrich.com/blog/2012/how-to-load-native-jni-library-from-jar + * @see https://github.com/adamheinrich/native-utils + * + */ +public class NativeUtils { + + /** + * The minimum length a prefix for a file has to have according to {@link File#createTempFile(String, String)}}. + */ + private static final int MIN_PREFIX_LENGTH = 3; + public static final String NATIVE_FOLDER_PATH_PREFIX = "nativeutils"; + + /** + * Temporary directory which will contain the DLLs. + */ + private static File temporaryDir; + + /** + * Private constructor - this class will never be instanced + */ + private NativeUtils() { + } + + /** + * Loads library from current JAR archive + * + * The file from JAR is copied into system temporary directory and then loaded. The temporary file is deleted after + * exiting. + * Method uses String as filename because the pathname is "abstract", not system-dependent. + * + * @param path The path of file inside JAR as absolute path (beginning with '/'), e.g. /package/File.ext + * @throws IOException If temporary file creation or read/write operation fails + * @throws IllegalArgumentException If source file (param path) does not exist + * @throws IllegalArgumentException If the path is not absolute or if the filename is shorter than three characters + * (restriction of {@link File#createTempFile(String, String)}). + * @throws FileNotFoundException If the file could not be found inside the JAR. + */ + public static void loadLibraryFromJar(String path) throws IOException { + + if (null == path || !path.startsWith("/")) { + throw new IllegalArgumentException("The path has to be absolute (start with '/')."); + } + + // Obtain filename from path + String[] parts = path.split("/"); + String filename = (parts.length > 1) ? parts[parts.length - 1] : null; + + // Check if the filename is okay + if (filename == null || filename.length() < MIN_PREFIX_LENGTH) { + throw new IllegalArgumentException("The filename has to be at least 3 characters long."); + } + + // Prepare temporary file + if (temporaryDir == null) { + temporaryDir = createTempDirectory(NATIVE_FOLDER_PATH_PREFIX); + temporaryDir.deleteOnExit(); + } + + File temp = new File(temporaryDir, filename); + + try (InputStream is = NativeUtils.class.getResourceAsStream(path)) { + Files.copy(is, temp.toPath(), StandardCopyOption.REPLACE_EXISTING); + } catch (IOException e) { + temp.delete(); + throw e; + } catch (NullPointerException e) { + temp.delete(); + throw new FileNotFoundException("File " + path + " was not found inside JAR."); + } + + try { + System.load(temp.getAbsolutePath()); + } finally { + if (isPosixCompliant()) { + // Assume POSIX compliant file system, can be deleted after loading + temp.delete(); + } else { + // Assume non-POSIX, and don't delete until last file descriptor closed + temp.deleteOnExit(); + } + } + } + + private static boolean isPosixCompliant() { + try { + return FileSystems.getDefault() + .supportedFileAttributeViews() + .contains("posix"); + } catch (FileSystemNotFoundException + | ProviderNotFoundException + | SecurityException e) { + return false; + } + } + + private static File createTempDirectory(String prefix) throws IOException { + String tempDir = System.getProperty("java.io.tmpdir"); + File generatedDir = new File(tempDir, prefix + System.nanoTime()); + + if (!generatedDir.mkdir()) + throw new IOException("Failed to create temp directory " + generatedDir.getName()); + + return generatedDir; + } +} diff --git a/src/main/java/module-info.java b/src/main/java/module-info.java index d287fa9..825652f 100644 --- a/src/main/java/module-info.java +++ b/src/main/java/module-info.java @@ -14,4 +14,5 @@ open module com.sparrowwallet.drongo { exports com.sparrowwallet.drongo.wallet; exports com.sparrowwallet.drongo.policy; exports com.sparrowwallet.drongo.uri; + exports org.bitcoin; } \ No newline at end of file diff --git a/src/main/java/org/bitcoin/NativeSecp256k1.java b/src/main/java/org/bitcoin/NativeSecp256k1.java new file mode 100644 index 0000000..2cda777 --- /dev/null +++ b/src/main/java/org/bitcoin/NativeSecp256k1.java @@ -0,0 +1,910 @@ +/* + * Copyright 2013 Google Inc. + * Copyright 2014-2016 the libsecp256k1 contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.bitcoin; + +import java.nio.Buffer; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; + +import java.math.BigInteger; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantReadWriteLock; +import static org.bitcoin.NativeSecp256k1Util.*; + +/** + *

This class holds native methods to handle ECDSA verification.

+ * + *

You can find an example library that can be used for this at https://github.com/bitcoin-core/secp256k1

+ * + *

To build secp256k1 for use with bitcoinj, run + * `./configure --enable-jni --enable-experimental --enable-module-ecdh` + * and `make` then copy `.libs/libsecp256k1.so` to your system library path + * or point the JVM to the folder containing it with -Djava.library.path + *

+ */ +public class NativeSecp256k1 { + + private static final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock(); + private static final Lock r = rwl.readLock(); + private static final Lock w = rwl.writeLock(); + private static ThreadLocal nativeECDSABuffer = new ThreadLocal(); + /** + * Verifies the given secp256k1 signature in native code. + * Calling when enabled == false is undefined (probably library not loaded) + * + * @param data The data which was signed, must be exactly 32 bytes + * @param signature The signature + * @param pub The public key which did the signing + */ + public static boolean verify(byte[] data, byte[] signature, byte[] pub) { + checkArgument(data.length == 32 && signature.length <= 520 && pub.length <= 520); + + ByteBuffer byteBuff = nativeECDSABuffer.get(); + if (byteBuff == null || byteBuff.capacity() < 520) { + byteBuff = ByteBuffer.allocateDirect(520); + byteBuff.order(ByteOrder.nativeOrder()); + nativeECDSABuffer.set(byteBuff); + } + + safeRewind(byteBuff); + byteBuff.put(data); + byteBuff.put(signature); + byteBuff.put(pub); + + r.lock(); + try { + return secp256k1_ecdsa_verify(byteBuff, Secp256k1Context.getContext(), signature.length, pub.length) == 1; + } finally { + r.unlock(); + } + } + + /** + * libsecp256k1 Create an ECDSA signature. + * + * @param data Message hash, 32 bytes + * @param seckey ECDSA Secret key, 32 bytes + * @return sig byte array of signature + */ + public static byte[] sign(byte[] data, byte[] seckey) throws AssertFailException{ + checkArgument(data.length == 32 && seckey.length <= 32); + + ByteBuffer byteBuff = nativeECDSABuffer.get(); + if (byteBuff == null || byteBuff.capacity() < 32 + 32) { + byteBuff = ByteBuffer.allocateDirect(32 + 32); + byteBuff.order(ByteOrder.nativeOrder()); + nativeECDSABuffer.set(byteBuff); + } + + safeRewind(byteBuff); + byteBuff.put(data); + byteBuff.put(seckey); + + byte[][] retByteArray; + + r.lock(); + try { + retByteArray = secp256k1_ecdsa_sign(byteBuff, Secp256k1Context.getContext()); + } finally { + r.unlock(); + } + + byte[] sigArr = retByteArray[0]; + int sigLen = new BigInteger(new byte[] { retByteArray[1][0] }).intValue(); + int retVal = new BigInteger(new byte[] { retByteArray[1][1] }).intValue(); + + assertEquals(sigArr.length, sigLen, "Got bad signature length."); + + return retVal == 0 ? new byte[0] : sigArr; + } + + /** + * libsecp256k1 Create an ECDSA signature adding specified entropy. + * + * This can be used to include your own entropy to nonce generation + * in addition to the message and private key, while still doing so deterministically. + * + * In particular, this is used when generating low R signatures. + * See https://github.com/bitcoin/bitcoin/pull/13666/ + * + * @param data Message hash, 32 bytes + * @param seckey ECDSA Secret key, 32 bytes + * @param entropy 32 bytes of entropy + * @return sig byte array of signature + */ + public static byte[] signWithEntropy(byte[] data, byte[] seckey, byte[] entropy) throws AssertFailException{ + checkArgument(data.length == 32 && seckey.length == 32 && entropy.length == 32); + + ByteBuffer byteBuff = nativeECDSABuffer.get(); + if (byteBuff == null || byteBuff.capacity() < 32 + 32 + 32) { + byteBuff = ByteBuffer.allocateDirect(32 + 32 + 32); + byteBuff.order(ByteOrder.nativeOrder()); + nativeECDSABuffer.set(byteBuff); + } + safeRewind(byteBuff); + byteBuff.put(data); + byteBuff.put(seckey); + byteBuff.put(entropy); + + byte[][] retByteArray; + + r.lock(); + try { + retByteArray = secp256k1_ecdsa_sign_with_entropy(byteBuff, Secp256k1Context.getContext()); + } finally { + r.unlock(); + } + + byte[] sigArr = retByteArray[0]; + int sigLen = new BigInteger(new byte[] { retByteArray[1][0] }).intValue(); + int retVal = new BigInteger(new byte[] { retByteArray[1][1] }).intValue(); + + assertEquals(sigArr.length, sigLen, "Got bad signature length."); + + return retVal == 0 ? new byte[0] : sigArr; + } + + /** + * libsecp256k1 Seckey Verify - Verifies an ECDSA secret key + * + * @param seckey ECDSA Secret key, 32 bytes + * @return true if valid, false if invalid + */ + public static boolean secKeyVerify(byte[] seckey) { + checkArgument(seckey.length == 32); + + ByteBuffer byteBuff = nativeECDSABuffer.get(); + if (byteBuff == null || byteBuff.capacity() < seckey.length) { + byteBuff = ByteBuffer.allocateDirect(seckey.length); + byteBuff.order(ByteOrder.nativeOrder()); + nativeECDSABuffer.set(byteBuff); + } + + safeRewind(byteBuff); + byteBuff.put(seckey); + + r.lock(); + try { + return secp256k1_ec_seckey_verify(byteBuff,Secp256k1Context.getContext()) == 1; + } finally { + r.unlock(); + } + } + + + /** + * libsecp256k1 Compute Pubkey - computes public key from secret key + * + * @param seckey ECDSA Secret key, 32 bytes + * @param compressed Should the generated public key be compressed + * @return pubkey ECDSA Public key, 33 or 65 bytes + */ + public static byte[] computePubkey(byte[] seckey, boolean compressed) throws AssertFailException{ + checkArgument(seckey.length == 32); + + ByteBuffer byteBuff = nativeECDSABuffer.get(); + if (byteBuff == null || byteBuff.capacity() < seckey.length) { + byteBuff = ByteBuffer.allocateDirect(seckey.length); + byteBuff.order(ByteOrder.nativeOrder()); + nativeECDSABuffer.set(byteBuff); + } + + safeRewind(byteBuff); + byteBuff.put(seckey); + + byte[][] retByteArray; + + r.lock(); + try { + retByteArray = secp256k1_ec_pubkey_create(byteBuff, Secp256k1Context.getContext(), compressed); + } finally { + r.unlock(); + } + + byte[] pubArr = retByteArray[0]; + int pubLen = new BigInteger(new byte[] { retByteArray[1][0] }).intValue(); + int retVal = new BigInteger(new byte[] { retByteArray[1][1] }).intValue(); + + assertEquals(pubArr.length, pubLen, "Got bad pubkey length."); + + return retVal == 0 ? new byte[0]: pubArr; + } + + /** + * libsecp256k1 Cleanup - This destroys the secp256k1 context object + * This should be called at the end of the program for proper cleanup of the context. + */ + public static synchronized void cleanup() { + w.lock(); + try { + secp256k1_destroy_context(Secp256k1Context.getContext()); + } finally { + w.unlock(); + } + } + + public static long cloneContext() { + r.lock(); + try { + return secp256k1_ctx_clone(Secp256k1Context.getContext()); + } finally { r.unlock(); } + } + + /** + * libsecp256k1 PrivKey Tweak-Mul - Tweak seckey by multiplying to it + * + * @param seckey ECDSA Secret key, 32 bytes + * @param tweak some bytes to tweak with + */ + public static byte[] privKeyTweakMul(byte[] seckey, byte[] tweak) throws AssertFailException{ + checkArgument(seckey.length == 32); + + ByteBuffer byteBuff = nativeECDSABuffer.get(); + if (byteBuff == null || byteBuff.capacity() < seckey.length + tweak.length) { + byteBuff = ByteBuffer.allocateDirect(seckey.length + tweak.length); + byteBuff.order(ByteOrder.nativeOrder()); + nativeECDSABuffer.set(byteBuff); + } + + safeRewind(byteBuff); + byteBuff.put(seckey); + byteBuff.put(tweak); + + byte[][] retByteArray; + r.lock(); + try { + retByteArray = secp256k1_privkey_tweak_mul(byteBuff,Secp256k1Context.getContext()); + } finally { + r.unlock(); + } + + byte[] privArr = retByteArray[0]; + + int privLen = (byte) new BigInteger(new byte[] { retByteArray[1][0] }).intValue() & 0xFF; + int retVal = new BigInteger(new byte[] { retByteArray[1][1] }).intValue(); + + assertEquals(privArr.length, privLen, "Got bad pubkey length."); + + assertEquals(retVal, 1, "Failed return value check."); + + return privArr; + } + + /** + * libsecp256k1 PrivKey Tweak-Add - Tweak seckey by adding to it + * + * @param seckey ECDSA Secret key, 32 bytes + * @param tweak some bytes to tweak with + */ + public static byte[] privKeyTweakAdd(byte[] seckey, byte[] tweak) throws AssertFailException{ + checkArgument(seckey.length == 32); + + ByteBuffer byteBuff = nativeECDSABuffer.get(); + if (byteBuff == null || byteBuff.capacity() < seckey.length + tweak.length) { + byteBuff = ByteBuffer.allocateDirect(seckey.length + tweak.length); + byteBuff.order(ByteOrder.nativeOrder()); + nativeECDSABuffer.set(byteBuff); + } + + safeRewind(byteBuff); + byteBuff.put(seckey); + byteBuff.put(tweak); + + byte[][] retByteArray; + r.lock(); + try { + retByteArray = secp256k1_privkey_tweak_add(byteBuff,Secp256k1Context.getContext()); + } finally { + r.unlock(); + } + + byte[] privArr = retByteArray[0]; + + int privLen = (byte) new BigInteger(new byte[] { retByteArray[1][0] }).intValue() & 0xFF; + int retVal = new BigInteger(new byte[] { retByteArray[1][1] }).intValue(); + + assertEquals(privArr.length, privLen, "Got bad pubkey length."); + + assertEquals(retVal, 1, "Failed return value check."); + + return privArr; + } + + /** + * libsecp256k1 PubKey Tweak-Add - Tweak pubkey by adding to it + * + * @param pubkey ECDSA Public key, 33 or 65 bytes + * @param tweak some bytes to tweak with + * @param compressed should the output public key be compressed + */ + public static byte[] pubKeyTweakAdd(byte[] pubkey, byte[] tweak, boolean compressed) throws AssertFailException{ + checkArgument(pubkey.length == 33 || pubkey.length == 65); + + ByteBuffer byteBuff = nativeECDSABuffer.get(); + if (byteBuff == null || byteBuff.capacity() < pubkey.length + tweak.length) { + byteBuff = ByteBuffer.allocateDirect(pubkey.length + tweak.length); + byteBuff.order(ByteOrder.nativeOrder()); + nativeECDSABuffer.set(byteBuff); + } + + safeRewind(byteBuff); + byteBuff.put(pubkey); + byteBuff.put(tweak); + + byte[][] retByteArray; + r.lock(); + try { + retByteArray = secp256k1_pubkey_tweak_add(byteBuff, Secp256k1Context.getContext(), pubkey.length, compressed); + } finally { + r.unlock(); + } + + byte[] pubArr = retByteArray[0]; + + int pubLen = (byte) new BigInteger(new byte[] { retByteArray[1][0] }).intValue() & 0xFF; + int retVal = new BigInteger(new byte[] { retByteArray[1][1] }).intValue(); + + assertEquals(pubArr.length, pubLen, "Got bad pubkey length."); + + assertEquals(retVal, 1, "Failed return value check."); + + return pubArr; + } + + /** + * libsecp256k1 PubKey Tweak-Mul - Tweak pubkey by multiplying to it + * + * @param pubkey ECDSA Public key, 33 or 65 bytes + * @param tweak some bytes to tweak with + * @param compressed should the output public key be compressed + */ + public static byte[] pubKeyTweakMul(byte[] pubkey, byte[] tweak, boolean compressed) throws AssertFailException{ + checkArgument(pubkey.length == 33 || pubkey.length == 65); + + ByteBuffer byteBuff = nativeECDSABuffer.get(); + if (byteBuff == null || byteBuff.capacity() < pubkey.length + tweak.length) { + byteBuff = ByteBuffer.allocateDirect(pubkey.length + tweak.length); + byteBuff.order(ByteOrder.nativeOrder()); + nativeECDSABuffer.set(byteBuff); + } + + safeRewind(byteBuff); + byteBuff.put(pubkey); + byteBuff.put(tweak); + + byte[][] retByteArray; + r.lock(); + try { + retByteArray = secp256k1_pubkey_tweak_mul(byteBuff,Secp256k1Context.getContext(), pubkey.length, compressed); + } finally { + r.unlock(); + } + + byte[] pubArr = retByteArray[0]; + + int pubLen = (byte) new BigInteger(new byte[] { retByteArray[1][0] }).intValue() & 0xFF; + int retVal = new BigInteger(new byte[] { retByteArray[1][1] }).intValue(); + + assertEquals(pubArr.length, pubLen, "Got bad pubkey length."); + + assertEquals(retVal, 1, "Failed return value check."); + + return pubArr; + } + + /** + * libsecp256k1 PubKey Combine - Add pubkeys together + * + * @param pubkeys array of ECDSA Public key, 33 or 65 bytes each + * @param compressed should the output public key be compressed + */ + public static byte[] pubKeyCombine(byte[][] pubkeys, boolean compressed) throws AssertFailException{ + int numKeys = pubkeys.length; + checkArgument(numKeys > 0); + + int pubkeyLength = pubkeys[0].length; + checkArgument(pubkeyLength == 33 || pubkeyLength == 65); + + for (byte[] pubkey : pubkeys) { + checkArgument(pubkey.length == pubkeyLength); + } + + ByteBuffer byteBuff = nativeECDSABuffer.get(); + if (byteBuff == null || byteBuff.capacity() < numKeys * pubkeyLength) { + byteBuff = ByteBuffer.allocateDirect(numKeys * pubkeyLength); + byteBuff.order(ByteOrder.nativeOrder()); + nativeECDSABuffer.set(byteBuff); + } + + safeRewind(byteBuff); + for (byte[] pubkey : pubkeys) { + byteBuff.put(pubkey); + } + + byte[][] retByteArray; + r.lock(); + try { + retByteArray = secp256k1_ec_pubkey_combine(byteBuff,Secp256k1Context.getContext(), pubkeyLength, numKeys, compressed); + } finally { + r.unlock(); + } + + byte[] pubArr = retByteArray[0]; + + int pubLen = (byte) new BigInteger(new byte[] { retByteArray[1][0] }).intValue() & 0xFF; + int retVal = new BigInteger(new byte[] { retByteArray[1][1] }).intValue(); + + assertEquals(pubArr.length, pubLen, "Got bad pubkey length."); + + assertEquals(retVal, 1, "Failed return value check."); + + return pubArr; + } + + /** + * libsecp256k1 Decompress - Parse and decompress a variable-length pub key + * + * @param pubkey ECDSA Public key, 33 or 65 bytes + */ + public static byte[] decompress(byte[] pubkey) throws AssertFailException{ + checkArgument(pubkey.length == 33 || pubkey.length == 65); + + ByteBuffer byteBuff = nativeECDSABuffer.get(); + if (byteBuff == null || byteBuff.capacity() < pubkey.length) { + byteBuff = ByteBuffer.allocateDirect(pubkey.length); + byteBuff.order(ByteOrder.nativeOrder()); + nativeECDSABuffer.set(byteBuff); + } + + safeRewind(byteBuff); + byteBuff.put(pubkey); + + byte[][] retByteArray; + r.lock(); + try { + retByteArray = secp256k1_ec_pubkey_decompress(byteBuff, Secp256k1Context.getContext(), pubkey.length); + } finally { + r.unlock(); + } + + byte[] pubArr = retByteArray[0]; + + int pubLen = (byte) new BigInteger(new byte[] { retByteArray[1][0] }).intValue() & 0xFF; + int retVal = new BigInteger(new byte[] { retByteArray[1][1] }).intValue(); + + assertEquals(pubArr.length, pubLen, "Got bad pubkey length."); + + assertEquals(retVal, 1, "Failed return value check."); + + return pubArr; + } + + /** + * libsecp256k1 IsValidPubKey - Checks if a pubkey is valid + * + * @param pubkey ECDSA Public key, 33 or 65 bytes + */ + public static boolean isValidPubKey(byte[] pubkey) { + if (!(pubkey.length == 33 || pubkey.length == 65)) { + return false; + } + + ByteBuffer byteBuff = nativeECDSABuffer.get(); + if (byteBuff == null || byteBuff.capacity() < pubkey.length) { + byteBuff = ByteBuffer.allocateDirect(pubkey.length); + byteBuff.order(ByteOrder.nativeOrder()); + nativeECDSABuffer.set(byteBuff); + } + + safeRewind(byteBuff); + byteBuff.put(pubkey); + + byte[][] retByteArray; + r.lock(); + try { + retByteArray = secp256k1_ec_pubkey_decompress(byteBuff, Secp256k1Context.getContext(), pubkey.length); + } finally { + r.unlock(); + } + + int retVal = new BigInteger(new byte[] { retByteArray[1][1] }).intValue(); + + return retVal == 1; + } + + /** + * libsecp256k1 create ECDH secret - constant time ECDH calculation + * + * @param seckey byte array of secret key used in exponentiaion + * @param pubkey byte array of public key used in exponentiaion + */ + public static byte[] createECDHSecret(byte[] seckey, byte[] pubkey) throws AssertFailException{ + checkArgument(seckey.length <= 32 && pubkey.length <= 65); + + ByteBuffer byteBuff = nativeECDSABuffer.get(); + if (byteBuff == null || byteBuff.capacity() < 32 + pubkey.length) { + byteBuff = ByteBuffer.allocateDirect(32 + pubkey.length); + byteBuff.order(ByteOrder.nativeOrder()); + nativeECDSABuffer.set(byteBuff); + } + + safeRewind(byteBuff); + byteBuff.put(seckey); + byteBuff.put(pubkey); + + byte[][] retByteArray; + r.lock(); + try { + retByteArray = secp256k1_ecdh(byteBuff, Secp256k1Context.getContext(), pubkey.length); + } finally { + r.unlock(); + } + + byte[] resArr = retByteArray[0]; + int retVal = new BigInteger(new byte[] { retByteArray[1][0] }).intValue(); + + assertEquals(resArr.length, 32, "Got bad result length."); + assertEquals(retVal, 1, "Failed return value check."); + + return resArr; + } + + /** + * libsecp256k1 schnorr sign - generates a BIP 340 Schnorr signature + * + * @param data message to sign + * @param secKey key to sign with + */ + public static byte[] schnorrSign(byte[] data, byte[] secKey, byte[] auxRand) throws AssertFailException { + checkArgument(data.length == 32 && secKey.length == 32 && auxRand.length == 32); + + ByteBuffer byteBuff = nativeECDSABuffer.get(); + if (byteBuff == null || byteBuff.capacity() < 32 + 32 + 32) { + byteBuff = ByteBuffer.allocateDirect(32 + 32 + 32); + byteBuff.order(ByteOrder.nativeOrder()); + nativeECDSABuffer.set(byteBuff); + } + byteBuff.rewind(); + byteBuff.put(data); + byteBuff.put(secKey); + byteBuff.put(auxRand); + + byte[][] retByteArray; + r.lock(); + try { + retByteArray = secp256k1_schnorrsig_sign(byteBuff, Secp256k1Context.getContext()); + } finally { + r.unlock(); + } + + byte[] sigArray = retByteArray[0]; + int retVal = new BigInteger(new byte[]{retByteArray[1][0]}).intValue(); + + assertEquals(retVal, 1, "Failed return value check."); + + return sigArray; + } + + /** + * libsecp256k1 schnorr sign - generates a BIP 340 Schnorr signature + * + * @param data message to sign + * @param secKey key to sign with + * @param nonce the nonce (k value) used in signing + */ + public static byte[] schnorrSignWithNonce(byte[] data, byte[] secKey, byte[] nonce) throws AssertFailException { + checkArgument(data.length == 32 && secKey.length == 32 && nonce.length == 32); + + ByteBuffer byteBuff = nativeECDSABuffer.get(); + if (byteBuff == null || byteBuff.capacity() < 32 + 32 + 32) { + byteBuff = ByteBuffer.allocateDirect(32 + 32 + 32); + byteBuff.order(ByteOrder.nativeOrder()); + nativeECDSABuffer.set(byteBuff); + } + byteBuff.rewind(); + byteBuff.put(data); + byteBuff.put(secKey); + byteBuff.put(nonce); + + byte[][] retByteArray; + r.lock(); + try { + retByteArray = secp256k1_schnorrsig_sign_with_nonce(byteBuff, Secp256k1Context.getContext()); + } finally { + r.unlock(); + } + + byte[] sigArray = retByteArray[0]; + int retVal = new BigInteger(new byte[]{retByteArray[1][0]}).intValue(); + + assertEquals(retVal, 1, "Failed return value check."); + + return sigArray; + } + + /* + public static byte[] schnorrComputeSigPoint(byte[] data, byte[] nonce, byte[] pubkey, boolean compressed) throws AssertFailException { + checkArgument(data.length == 32 && nonce.length == 32 && pubkey.length == 32); + + ByteBuffer byteBuff = nativeECDSABuffer.get(); + if (byteBuff == null || byteBuff.capacity() < 32 + 32 + 32) { + byteBuff = ByteBuffer.allocateDirect(32 + 32 + 32); + byteBuff.order(ByteOrder.nativeOrder()); + nativeECDSABuffer.set(byteBuff); + } + byteBuff.rewind(); + byteBuff.put(data); + byteBuff.put(nonce); + byteBuff.put(pubkey); + + byte[][] retByteArray; + r.lock(); + try { + retByteArray = secp256k1_schnorrsig_compute_sigpoint(byteBuff, Secp256k1Context.getContext(), compressed); + } finally { + r.unlock(); + } + + byte[] pointArray = retByteArray[0]; + int outputLen = new BigInteger(new byte[] { retByteArray[1][0] }).intValue() & 0xFF; + int retVal = new BigInteger(new byte[] { retByteArray[1][1] }).intValue(); + + assertEquals(pointArray.length, outputLen, "Got bad point length."); + assertEquals(retVal, 1, "Failed return value check."); + + return pointArray; + } + */ + + /** + * libsecp256k1 schnorr verify - verifies BIP 340 Schnorr signatures + * + * @param sig signature to verify + * @param data message the signature has signed + * @param pubx the key that did the signing + */ + public static boolean schnorrVerify(byte[] sig, byte[] data, byte[] pubx) throws AssertFailException { + checkArgument(sig.length == 64 && data.length == 32 && pubx.length == 32); + + ByteBuffer byteBuffer = nativeECDSABuffer.get(); + if (byteBuffer == null || byteBuffer.capacity() < 64 + 32 + 32) { + byteBuffer = ByteBuffer.allocateDirect(64 + 32 + 32); + byteBuffer.order(ByteOrder.nativeOrder()); + nativeECDSABuffer.set(byteBuffer); + } + byteBuffer.rewind(); + byteBuffer.put(sig); + byteBuffer.put(data); + byteBuffer.put(pubx); + + r.lock(); + try { + return secp256k1_schnorrsig_verify(byteBuffer, Secp256k1Context.getContext()) == 1; + } finally { + r.unlock(); + } + } + + public static byte[] adaptorSign(byte[] seckey, byte[] adaptorPoint, byte[] data, byte[] auxRand) throws AssertFailException{ + checkArgument(seckey.length == 32 && + data.length == 32 && + (adaptorPoint.length == 33 || adaptorPoint.length == 65) && + auxRand.length == 32); + + ByteBuffer byteBuff = nativeECDSABuffer.get(); + if (byteBuff == null || byteBuff.capacity() < 32 + 32 + adaptorPoint.length + 32) { + byteBuff = ByteBuffer.allocateDirect(32 + 32 + adaptorPoint.length + 32); + byteBuff.order(ByteOrder.nativeOrder()); + nativeECDSABuffer.set(byteBuff); + } + byteBuff.rewind(); + byteBuff.put(seckey); + byteBuff.put(adaptorPoint); + byteBuff.put(data); + byteBuff.put(auxRand); + + byte[][] retByteArray; + + r.lock(); + try { + retByteArray = secp256k1_ecdsa_adaptor_sign(byteBuff, Secp256k1Context.getContext(), adaptorPoint.length); + } finally { + r.unlock(); + } + + byte[] sigArr = retByteArray[0]; + int retVal = new BigInteger(new byte[] { retByteArray[1][0] }).intValue(); + + if (retVal == 0) { + return new byte[]{}; + } else { + return sigArr; + } + } + + public static boolean adaptorVerify(byte[] adaptorSig, byte[] pubKey, byte[] data, byte[] adaptorPoint) throws AssertFailException{ + checkArgument(data.length == 32 && + adaptorSig.length == 162 && + (pubKey.length == 33 || pubKey.length == 65) && + adaptorPoint.length == pubKey.length); + + ByteBuffer byteBuff = nativeECDSABuffer.get(); + int buffLen = 32 + 162 + pubKey.length + adaptorPoint.length; + if (byteBuff == null || byteBuff.capacity() < buffLen) { + byteBuff = ByteBuffer.allocateDirect(buffLen); + byteBuff.order(ByteOrder.nativeOrder()); + nativeECDSABuffer.set(byteBuff); + } + byteBuff.rewind(); + byteBuff.put(adaptorSig); + byteBuff.put(pubKey); + byteBuff.put(data); + byteBuff.put(adaptorPoint); + + r.lock(); + try { + return secp256k1_ecdsa_adaptor_sig_verify(byteBuff, Secp256k1Context.getContext(), pubKey.length) == 1; + } finally { + r.unlock(); + } + } + + public static byte[] adaptorAdapt(byte[] adaptorSec, byte[] adaptorSig) throws AssertFailException{ + checkArgument(adaptorSec.length == 32 && adaptorSig.length == 162); + + ByteBuffer byteBuff = nativeECDSABuffer.get(); + if (byteBuff == null || byteBuff.capacity() < 32 + 162) { + byteBuff = ByteBuffer.allocateDirect(32 + 162); + byteBuff.order(ByteOrder.nativeOrder()); + nativeECDSABuffer.set(byteBuff); + } + byteBuff.rewind(); + byteBuff.put(adaptorSec); + byteBuff.put(adaptorSig); + + byte[][] retByteArray; + + r.lock(); + try { + retByteArray = secp256k1_ecdsa_adaptor_adapt(byteBuff, Secp256k1Context.getContext()); + } finally { + r.unlock(); + } + + byte[] sigArr = retByteArray[0]; + int sigLen = new BigInteger(new byte[] { retByteArray[1][0] }).intValue(); + int retVal = new BigInteger(new byte[] { retByteArray[1][1] }).intValue(); + + assertEquals(sigArr.length, sigLen, "Got bad signature length."); + + return retVal == 0 ? new byte[0] : sigArr; + } + + public static byte[] adaptorExtractSecret(byte[] sig, byte[] adaptorSig, byte[] adaptor) throws AssertFailException{ + checkArgument(sig.length <= 520 && (adaptor.length == 33 || adaptor.length == 65) && adaptorSig.length == 162); + + ByteBuffer byteBuff = nativeECDSABuffer.get(); + if (byteBuff == null || byteBuff.capacity() < sig.length + adaptor.length + 162) { + byteBuff = ByteBuffer.allocateDirect(sig.length + adaptor.length + 162); + byteBuff.order(ByteOrder.nativeOrder()); + nativeECDSABuffer.set(byteBuff); + } + byteBuff.rewind(); + byteBuff.put(sig); + byteBuff.put(adaptorSig); + byteBuff.put(adaptor); + + byte[][] retByteArray; + + r.lock(); + try { + retByteArray = secp256k1_ecdsa_adaptor_extract_secret(byteBuff, Secp256k1Context.getContext(), sig.length, adaptor.length); + } finally { + r.unlock(); + } + + byte[] sigArr = retByteArray[0]; + int retVal = new BigInteger(new byte[] { retByteArray[1][0] }).intValue(); + + return retVal == 0 ? new byte[0] : sigArr; + } + + /** + * libsecp256k1 randomize - updates the context randomization + * + * @param seed 32-byte random seed + */ + public static synchronized boolean randomize(byte[] seed) throws AssertFailException{ + checkArgument(seed.length == 32); + + ByteBuffer byteBuff = nativeECDSABuffer.get(); + if (byteBuff == null || byteBuff.capacity() < seed.length) { + byteBuff = ByteBuffer.allocateDirect(seed.length); + byteBuff.order(ByteOrder.nativeOrder()); + nativeECDSABuffer.set(byteBuff); + } + safeRewind(byteBuff); + byteBuff.put(seed); + + w.lock(); + try { + return secp256k1_context_randomize(byteBuff, Secp256k1Context.getContext()) == 1; + } finally { + w.unlock(); + } + } + + /** + * This helper method is needed to resolve issue 1524 on bitcoin-s + * This is because the API changed for ByteBuffer between jdks < 9 and jdk >= 9 + * In the earlier versions of the jdk, a [[java.nio.Buffer]] is returned, but greather than jdk 8 + * returns a [[ByteBuffer]]. This causes issues when compiling with jdk 11 but running with jdk 8 + * as the APIs are incompatible. + * @see https://github.com/bitcoin-s/bitcoin-s/issues/1524 + * @param byteBuff + */ + private static void safeRewind(ByteBuffer byteBuff) { + ((Buffer) byteBuff).rewind(); + } + + private static native long secp256k1_ctx_clone(long context); + + private static native int secp256k1_context_randomize(ByteBuffer byteBuff, long context); + + private static native byte[][] secp256k1_privkey_tweak_add(ByteBuffer byteBuff, long context); + + private static native byte[][] secp256k1_privkey_tweak_mul(ByteBuffer byteBuff, long context); + + private static native byte[][] secp256k1_pubkey_tweak_add(ByteBuffer byteBuff, long context, int pubLen, boolean compressed); + + private static native byte[][] secp256k1_pubkey_tweak_mul(ByteBuffer byteBuff, long context, int pubLen, boolean compressed); + + private static native void secp256k1_destroy_context(long context); + + private static native int secp256k1_ecdsa_verify(ByteBuffer byteBuff, long context, int sigLen, int pubLen); + + private static native byte[][] secp256k1_ecdsa_sign(ByteBuffer byteBuff, long context); + + private static native byte[][] secp256k1_ecdsa_sign_with_entropy(ByteBuffer byteBuff, long context); + + private static native int secp256k1_ec_seckey_verify(ByteBuffer byteBuff, long context); + + private static native byte[][] secp256k1_ec_pubkey_create(ByteBuffer byteBuff, long context, boolean compressed); + + private static native byte[][] secp256k1_ec_pubkey_combine(ByteBuffer byteBuff, long context, int pubLen, int numKeys, boolean compressed); + + private static native byte[][] secp256k1_ec_pubkey_decompress(ByteBuffer byteBuff, long context, int inputLen); + + private static native byte[][] secp256k1_ecdh(ByteBuffer byteBuff, long context, int inputLen); + + private static native byte[][] secp256k1_schnorrsig_sign(ByteBuffer byteBuff, long context); + + private static native byte[][] secp256k1_schnorrsig_sign_with_nonce(ByteBuffer byteBuff, long context); + + //private static native byte[][] secp256k1_schnorrsig_compute_sigpoint(ByteBuffer byteBuff, long context, boolean compressed); + + private static native int secp256k1_schnorrsig_verify(ByteBuffer byteBuffer, long context); + + private static native byte[][] secp256k1_ecdsa_adaptor_sign(ByteBuffer byteBuff, long context, int adaptorLen); + + private static native int secp256k1_ecdsa_adaptor_sig_verify(ByteBuffer byteBuff, long context, int pubKeyLen); + + private static native byte[][] secp256k1_ecdsa_adaptor_adapt(ByteBuffer byteBuff, long context); + + private static native byte[][] secp256k1_ecdsa_adaptor_extract_secret(ByteBuffer byteBuff, long context, int sigLen, int adaptorLen); +} diff --git a/src/main/java/org/bitcoin/NativeSecp256k1Util.java b/src/main/java/org/bitcoin/NativeSecp256k1Util.java new file mode 100644 index 0000000..e8bbe09 --- /dev/null +++ b/src/main/java/org/bitcoin/NativeSecp256k1Util.java @@ -0,0 +1,51 @@ +/* + * Copyright 2014-2016 the libsecp256k1 contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.bitcoin; + +public class NativeSecp256k1Util{ + + public static void assertEquals( int val, int val2, String message ) throws AssertFailException{ + if( val != val2 ) + throw new AssertFailException("FAIL: " + message); + } + + public static void assertEquals( boolean val, boolean val2, String message ) throws AssertFailException{ + if( val != val2 ) + throw new AssertFailException("FAIL: " + message); + else + System.out.println("PASS: " + message); + } + + public static void assertEquals( String val, String val2, String message ) throws AssertFailException{ + if( !val.equals(val2) ) + throw new AssertFailException("FAIL: " + message); + else + System.out.println("PASS: " + message); + } + + public static class AssertFailException extends Exception { + public AssertFailException(String message) { + super( message ); + } + } + + public static void checkArgument(boolean expression) { + if (!expression) { + throw new IllegalArgumentException(); + } + } +} diff --git a/src/main/java/org/bitcoin/Secp256k1Context.java b/src/main/java/org/bitcoin/Secp256k1Context.java new file mode 100644 index 0000000..5034987 --- /dev/null +++ b/src/main/java/org/bitcoin/Secp256k1Context.java @@ -0,0 +1,55 @@ +package org.bitcoin; + +import com.sparrowwallet.drongo.NativeUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; + +public class Secp256k1Context { + + private static final boolean enabled; // true if the library is loaded + private static final long context; // ref to pointer to context obj + + private static final Logger log = LoggerFactory.getLogger(Secp256k1Context.class); + + static { // static initializer + enabled = loadLibrary(); + if(enabled) { + context = secp256k1_init_context(); + } else { + context = -1; + } + } + + public static boolean isEnabled() { + return enabled; + } + + public static long getContext() { + if (!enabled) + return -1; // sanity check + return context; + } + + private static boolean loadLibrary() { + try { + String osName = System.getProperty("os.name"); + if(osName.startsWith("Mac")) { + NativeUtils.loadLibraryFromJar("/native/osx/x64/libsecp256k1.dylib"); + } else if(osName.startsWith("Windows")) { + NativeUtils.loadLibraryFromJar("/native/windows/x64/libsecp256k1-0.dll"); + } else { + NativeUtils.loadLibraryFromJar("/native/linux/x64/libsecp256k1.so"); + } + + return true; + } catch(IOException e) { + log.debug("Error loading libsecp256k1 library", e); + } + + return false; + } + + private static native long secp256k1_init_context(); +} diff --git a/src/main/resources/native/linux/x64/libsecp256k1.so b/src/main/resources/native/linux/x64/libsecp256k1.so new file mode 100755 index 0000000000000000000000000000000000000000..ce37197bae4bd06b932f63a171495a36a76b5c86 GIT binary patch literal 244824 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%0D9RA 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�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 u*@O%yx2x3db-@taC#}$>~G=)wm@O|0tl9=SX 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¥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 z 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
$Ln5gPB|4M`*0_RMg0#pO%j|bSVQ$n--Ctc*G z>|Dg@41PD7#OM$KkaW)-NAbJvD?aw zKuE$^kS3Lof{ZIfejSQQ#%!m^DB8&b&Ai}IEniI(6+BbvNLqmHtij?Qza$~Wk{3Gp z%>)=Bu>?^msmjIs@)h~owyGsK)auKKkB@3P9W(cPl@`SCz_LIPk2xQeM0WZ z9J5>8GFNSKc(GyJv`f+w6`ddDhHw6~*Bb0{7qF&BL}O}%|C=CV4>I$*}p(B2z}B4$b< z{rvnp(gXhDP!HP0Zz)9)9Oa5OzHoWS7I8d8+w`Kt|Kx(aD4jM_sDGSGw0c@CC?=Xyd3r~lo80D@ zZQFB+)M&&)a%SDVgRa#tVMordjnr4+3GG5cq z(;j)a1!bzi-#t8MG^nQ#jO=D;j$2hkQuyh>F-Y%;L%_m3a>Y8EMN zOe#I8cs{C8XMUnX5|)QS{cXzR(M`07rly0L?x`ccVe+&jF-|OQD@&*q=GZ3;qE7OP zVMzG*NpQq+O0!p6ShdMoQv>gLlxMyjF40qbsw`aJ=KOJCN=<~5+tn~B`uM1Yc>K~x z47N&H_TAG1&Dqu2G`7!;r5K!}h?9OcB*ac`T3uphcl{N|1+@2>E>}rI4G=>rCDJel zSb6WYoR<2sQXj3~(y|mtba6}K5J|Jwe9+)F2sI#EJM=O2!i{f@lQPU>t1`xxuxMX5 zcuxQJ!)o(mGcz*{%r~SWneMqXJ}e)QJHB;&Zu^Egq8*?_Y&B2j`v5!FuddALIS+fw zJKSZ7%ZeHbdjBGJ`gO-AX+_ne=6tyh)d3SIpSn|`&3zwNi}bp7k*6G> zuwU%$JJ#2y6mEvr%G@x3Dt#&IOUC`&7~5`Gv6JhSs=Vw#>m(%)?p@b=uUgiUNh?_H z%ur@P2OxQl3f7q`uaFxg`FMR6H@MxaYUJ`>FJxcHGg^T$l4?5w=MtyB?Pv%|#z= zc=>ARD;BAy7)rJAF3R0#J%KLT`1~FpPlkD{N1q8A{2zW9F{4wVh}#XN?rCd;PLJK{ zHL=j6*PX<2?9hlC;Gm4NwMQIbQAL5RRogFs8|?TX5I(ap(`KN~JVIKL;w4+MqF}>c zyj-=cwu;J0`;{PK@14U-)xpsC%koqN2AT?tY3OW+Z;zq878M_Td0$tm(k-$xj3%#;{PN;s*5*VYpj)jV4w4j1`jlG=V53=r}UJqW|2j2N$ zrz{d0{Dg^$r|Z=wlL+$W-ghaFGT&%4k8g{vd%|kRerdYK^+kC>=1+#=*GbsEZOK0= zuwz{~N9Ru2jJGFzBA#hB6Yv4nqfGaO@uv=2uJ*uB@{&?=>-G<))khD8N^hXa&Im(G zYrfadnp&N~>E5HWz&N!Ou9+ffrBY#i`+i_hILk@0w#OmIC~5h2!18mef^0uEISZog zm(mwcqlWw>W!Yv@EUHaLxSzCG(ymgy)h&+a)*E)XpHjx-`2^cz@Iquh#^JM~>LOtk zcbJw1x9L~I@HSj_!H*=Uf(q5JbT}p4-&-_m2~oJ$J#4kR%$Bm)pgA3|dHN~5BVSF$ zXjX-cX863Sdy3myFAF)FD5F&e*}1C40Ua@2;Nun&sJd8(&Gi^h)(Adn)A-MUg0p z2`|!5zA6g&2?<&ajhqMOu{%q5Iz#lG%;psvmpw}GY?S%pNm+WWrg*%!ZC6<~SY2uG zG2Y*mIo$U(&Ws%zKqB&TdxR45%Cm37-`0+d{qLQdKS#t8z%1c9rhd%QY$8i*O@mg2Z<^5jp^SUv z`#Xxe5{q}!&|14Zmcxzd*{XkHtWj8yt%+cF8b6R-4r_WhmvilY4aQEJT-^cGT|vZ8t1kxRYR)8G zz8eqOeS29{e~bR{OC5%Zqd|Wn4+kh3gWPl0QB;v9eoA6DKR0p|=GszqvQ+p;G^F$x z-(7wwnRKgRKF-BUHs3Kv*GHpVKn5eXhc?^IjBLV6V;CG%CgCCfY)1c7bLb>b`^4?8N8b%G}D-L4?1}gJb@6* zm_kdTBK%}AV<#j4*Sv31%Drphz%T4w#2$}bl%Fc()gT1%qr$tLGa$J8z6?P_q6>+4$Sj`Lar z_r8m^Ok@Rj_>1^Ia%Z`mX5p|IPu5~~L0E^{9TqiG#aSp(qYQmVqI6Kwoxtp57+tO< zY?NJ3ujF@zYoFI zy4#TPW+uHhv9WxPt+MnoPwA0@Pz21$#KRH!$vU4DczGTlI@s0f(b*hMxE&(Kh4>t6 zcPq{u3@xVf_71BaGE&Lpd2tPTiI8I^^vPTt69oc2eDcPx=L2=4(*nz+9f`;!=*Jdq z3dmR&!O;~OLAQ}aPy;v;h+lXi+`6kjkgHR!qmU$7Vdgw4NkZSqKwcL1jWWDuta>1b zfsXpY3hnU&a)Yc3T0_!M-l(W>za>Wpm45i7(7w?Wj4zyb?thU~DG(pgFA;9Kp_iQ; zyZluKkx+K_^j=oaeo<#)W688ljSH=G;Ahs57W}8i4)Y%3N_olELh;JvE$$TP3{Y5} zYoDrp6DA2~8a#SWZqNBWj;v_kpM~oTW#5Z|HM4cnpC`)Cen*mym5ck*k+iwwrf$l* z1{#l?2)yB&FXsh38n_MB{4Ss?MrcrP8l4 zIDC40+)J?N{!4vn(r030dj=(s4p>>n2RXyu#xBE1_}Wh&;~*-OEY%>1>RhnCezG<* zztv5i&-6)oR4hn8SH}?REI>X}GTZY34Ot=*qQC02#=eVLmf8a8*wpJSY}3}@5i zOFACe z1|lliv)SPW37pDVrTI);bh@C}dxcw%zq|EYml9_)rly zN;=?dV@EX@x@cD2(@(PuTewB4X-XDQpzhVUIc0(`Ge|=|y6Av%U$gW1+K!O{#`KNH z3=RTET!oh!jo$;HP9M024->VnBZOF&kkxJsl{ayOB{`HR%~hFjuVJM0mX>1iMJMqS zzO}TF_Z~y^C#yh*5~JgYd)@PtG^W$t^u<%7Me+2-XGXDys$Zb2J)Px_w8LTMEaw{2 z=&QcgPK?OKuAll{;7)$@gVqbcqOQ(($5nE%Y>k`0bVrcoQFEXaC+dwVIwj1zwDDF2 z_rwmxZp{Zed4$}wSH(fMnMBj)Jz0Et!>IeNu*D~tICKx%QW6TM@^7ezbx`>iF}B4r z9Cpb}oGn!8xDP2ZT#b)K^$ItT7Dx*4k7Qq~Dr})=b(+YoUNCDqacVQ9-|gMP6HJ{E za&%mKQl#-r!q(NOVSHex*<;n0Hf#z*fa!@Te8F2sTO7I0;aXl(wq*2R4cGkbwjL9& zX!}rc4%U36cFHB{^aPZT`j4i@R3hQAnqNs#EEmF9n&H+u8?)oy$$p9V_L1jn95v+3 zW2rqlZbrY&KBV1851uCPqum{oRtZea6Dxy}3Ma**xoBg*V0ci5zDVc79YXi4rru&% zoR8~07c!o1x@dx;Wq-6mCo4@$>Ma+`=CVT#Y@)~hoc`4_q3Y87H+_Sb)sEiT= zXUf~zpGahd(W_ZBp|)o=dNCL)2bZSqMUwaxskus$`1WaF?lwr^Yl$)@YC19PN!}JLOvc(u%b5lbrOXl zE_<`tH>GO>1z<>lcU5(f54cggPdIUvy?wDns=d|)dGpiQb8WvH7jg|BcJF$vAxPKV z+sox=VGcN!(Im`d)37I)W1^D`>JpYKZTN!6-SNB*k$G}!rzfBCoCfRaqgk$-CW#v#d?AR5GRn3}jLd60J3IHV{ze^uvg(|?6@@)QH}@Sk zdi9{>z@*NE540-?S0{8We=6)C-&4Qwlq%G zP`09Gq2$M$#vE>9I$K*HhrhI>C~Ew+qmrC#a$@G2R?>wBH_O zL(S7~+#{GdeL^W-Lm$;muBOa>5^;{#lBbAqr&$_%V=NZ=VEvm|WG}_po}acx{|g6n z<(CI%#j#OH6fqs7y|30zUR>BdySF@?b&>Vnc}$VTZ@xSGH3{m2vU{+W6fKCKCWl6= zh3*BRFe34sqaUvfu!L+-Jyhk%s6r1N#!*$n&-m_PPo!!yXCAIU(r`fM%I{@9$!AP9 z6o3AW(5{Xu^%iS&Eg?PaYfALoX5~_i<~k}uEnCSO{qlyRc!?u|qAWbcR{bUIcppqS zk&hx_RIoB_D&6hB$9T6$)3KH?42gywUl?%daE3=`++m5zWgCCUSNbH@$bmxrmWdtJ zH!L}>WY{~UT7})r_$GP!fpr&g!}a7^&`ZRfrmGtrsuk>hl3K~@L+YewHf}{uUNOE0 zUkbc=QM*UVQe8GZc)nYQ!F%0!9{9vEDA3!pmaQhJ9A7-CWv~}*NT+d-#BR9nUOlp|%(oXI~VIffH@U`b3(9CwC**fP2+`U>9!JCpM zH_Ftr8ywVgQToydi;qmPKFWDRBEoG=BuKGQ zci3LrlBbMO!d#jQE)k3ty*Z@F(4Ikf^58-R5b$U^ng*Nr_o%7YIyX5KyrnX zLBh8%dWCWzJ@`O_;Si3O?s-V+8+=RRM)X@)? zW7YbYX!20t$UHS3id%XgZ^ZsGH5DnGEpm=tnvv_a&ll{5`{_5ea7u2DA%FI7{ku4=rwOYy?{wVun=vhV@T zhcygsdmi)#393z`?%7B|h<(vs%^FaRXHxaK16>@KWunxBoOFB$O5`hBaZ0;xmv`sv zxODf7v{dOlNY== zSnsgjF}<^#ktRxekzy1{H+KYeMy{+l|GcWsp{rf6-rar!o#+rFW>ke_tfS--8w1U1 z66Iy}(jCk^pIg*UO&<+umUH56q^;8U8P>d`WUZPs9q#4aI3SQCvZ0!`+O(Ih)Ot3@ z4lCP7sMfs$n@IZFp)#^+W`T#?xt;7?fwrd%%j{&q<|KToU~E0@a+^!UE4ONAs{7CC zeFe-~ZqpN&YYFsAzO}dQJ*ZR2AB;>1bX%_XJmb|xc`uGATqSF-Uju!7hERDX@i-ql z%cMokPBtgV*rku~E@d&&O<{J74RrW#f@yk_UL-4rg(*sON{27KrF;mtKa~W^ElBd+ zY;4UOEXnBh!F>^HXzqM=jDqfr%1X{-TeYEpeQ%b%lhJDaVF$eSD8@-~|1-XhcsPGC z*Kavr)Md5&Lq!wS=XnI;b5}jY>O)gQ=JQ~tSw>LHOWy80&i;ty;QSKT)P?=|Qe|6B zqpzBxd0(n%LT&WT9v8|jT>hh1{rqjTqH&Aw3fePfgpK9bPPFni`f`neM{kau(AyG zl0|`>T1D5P=@voXJ1CF1b`}CpPcc)v4!)aGDnoh&rWN`R&psE~zGpj+4ChByxcsu>%!(njZUFg#$riYxE$BD?PUz9hg|%rFN1#&PFcd^rgvHY@AT+XiLpQ};^lU81~L$xV9mQ0gAP z{tJWj!&Sz?INV(}l?E)XFB$hcv+bah)E;v%tFhv{ln$4f;j*UQ-wz1?V%-4PgbU@| zRRW5o!(?9ri#ve#i8}x`-C`!q7*luyl!OCX)2uwbL$(2lD1H_nj#@ zPFzX5WYRM2=7u+7L!}&txVHoo6G+J_MjK@9(mcOxAy}8-i=J5ehY6cLEpQZ!ML#Zn zZylyBf?8B8m_VZqJJlp3G|BuWy@quyltn#^=0K0k>f^EA!|zCQ2p7e zT!J$Weh1=B%0nC+Y;irgLG%1 z&ATcH6Xik7#^~Chm30A<;gc6dLdc6wrh0{yy`x3^mfJ&T!95iYXYK_$x3C{tirHGs zP8vIzL^~8wxOzNf*hf#A6De-Gw5y}mVaDHh!$Ub3GvG0m?Dl@_EyqiY*(tw{bqyHN z#MUt%9CPw}L_J8GL4L)%^&)}p=a^ov_HXcwt9!+hi^<0%lD$C)iJtU*i0}w2%k83y45yEXCdJ)P_-Z_aF4S%CAHxs>XaWX)W&=aTZ!wo zYmqp`RO&g*C&@pkCpT^1TC&f{JPGIyk&Yi)( zv=gNN!lpBvIUHf0dT6-WwPX&*-byIGjg2B~!iI9+2AT0mMMHyNg%cer+EKb-*vud~ zjdF7}S+dfWmhFH?N@wjGsm_S-O%=C}xKHFPniBBv4sk;v1`C13V^Ru1MJ>WRTI5GE zI`i?2smSsH_5m`Mjb$aKDsa>JhUqEi(hE*C_I>&H}nN=dBCfPHlo z`J{_?G>1Rj@C{9OZQAl>^VaCjln1nE!JB8h=uuIum$jqMEY}K}*VW!;W)tfNEP3s|7f56O^hO^+z}eTE!9pLZm(O%O7e{67 zENzQaLeX-=&pf3Q-gxOEOpr=TgpBO#!|hLy@=$YG%j)KZoH5mTY;sBotQ@J7vYdNc z){RfkRBwr@zu*zmFHYn z>scaR`4Bg&ay6`rVA0aT8Z*C?tcaI|Pw<_dcbeNQw;#%f1Uh77xS8bC;zK;%@B9Pp-D||;{CtnBk8|qEE7dyB*sMWM@ z$egAIkUTMB-VGE8x+T+5_wbHXyAa%Iu5tQgj`zmJG)6SWUY+>UW4!uxp>ilT?ys)x z7}2T`B8&QL(&l=V2sM6gQt zexju%-B5^q$*K##d(!?*EHk}D+S6jsJjxU50*`7Xs4}crlBYf@N;h{?cTjTjc+i+? zZX~H{q$iT>(~ro^u479gnN+4@J>vd|sY8~+s`H$xv6C`x z-X4C7e;=l|uQK~VPHpNEoRaOcw#c*whKoX64TU&c3-#rsdcJ%mm1#1Y%;A#&A#>GS@xI;yF>#Ac zMh0}P~mY~9z)etaG`ZA%7Ys?M>tzK-+gr4qNly11h!cyt`%uo99AYe}*Q z1Qj=v5XGX(^)%vw**ytY=??gvpj<5Nid4M^=F$UwU+jI>xLhmLPhqZ4l<@FK!e{AK zyla1RT|B6zKh$PQx4s_6@bp0B@my*IQbJg0%iWiQ=u%cTr4!sU-_E7ZRZ-{@BbjI` zrqGmnJ0mmJ7tj#>9&90(^e{*JZ*L8Wh<**3Hmio$F?(OfMv+w(+e^($tOgC2nJy4R z!{`HJGa25QY=tNHVe=IA0_CZSf$0MvD=kcWEW7?jh1i4ln6!xvLrTUH%1V?j?xIlQ z)@ModHyN*m1(B_%v}}cDO68|-e%ck zmL(teTkqIn<`^=a@Qaq~3)MA3(0Z!$a7VL-IDrNh2e$Be8utSDZ+lTFst1kb+^F5oM zQlN|X1Jy&3Gg&F~3uhOav6VCiIN7`qYV^=a%BhD##zdple#5Uyg6|k=^%;mX;gyD; zS#(LdJu$Umg+}VHL8Qg)qeG}zH?L`MpDm)}6$yzT3|IJU!bZW*7`YSaMCwL%e**E5 zeY)B6Qi-b9ru*++Wfb@1AHT9-WC0ABG@;=k5sj$3_>;0?EpBS-)ca2o6IMDB&Sw|q zMp)JJ0?nqQ>2W)zDQ9+LYe*y>$iJoS`zX~Q-TUg*R|mY^?vcQ(>rkQqEinj|TKOV;d9CAl=HoW!% zC+b|t<$G;Z6n^#NJlp+vn^0*32bBDZzU1P& zaKuG^z3g7q0=KH^5#}7Zf$#-U4Kdk6XciA8IKoWU6_|kAB6c0Jj6q+Jgz5`(a9uj? zuzuXvZfF$k z^UzU8dcgUTJUXjZ?it=B>AN!}SkDo1PWrRBp6h z)gdL<(l%TQyG!}{@%q$+9aPpJ-)M~QYqpqvI&IRCb>#f9w;Bam1rKHC3A(Gkw7l?8 z!q8VZW9Ce7lbH9L4@G%xA&MZtd_=r9_8}tePV}a6!SiG5k0>IrIxih6kC)EGjyE0Vozqw&yv10o^eb(ErBdI+wJ?N-^7Q&<#VPNW zBBS0q*FWylh0aY#Fw2F*OrGGFi7i#6`L^Auu=6I%U?R<+IGUkWr_#M2fhg~;3!R_R z7g@fl1OvI z9$~Cjc|ip&LCdFG)CW9_j&5ZHsz5f3PEkM%0`L3Lw*;kGpm;ygoHnFh6IxjgUA72hr z@N7IOiu}v3YE(uxK3PMHCQmzxX*<;XTZe;EfBdaz=aHn);9u+ciDj0x#1+NfGd;7~ z1JWm*31**w7}fV}NdLcY%i#lB(mI@)ayKI^x@j?nhWG&pZ0YOujv&PaG$_hx5(1fA zkO#BT%io>L5`s&^>&MVA_Xi(v4by(5JG!4Zax%M#xbP##*hVi3(8e|#bqo)dQq^jA z7-IzJwvu-uP9EXe7a)Q8LA;{~6l+^Fs%BE(SsswXy#Hz3bgQ+(7Q>&uIQ_`jDgFfG z>4{Kr=n-fLR59wLo{REgWs^dPg;M}T4*0{Mjx#UHv$5COHr0ALQO&__azvi$TlBQc zq*WJsLi)lugvn)L34>bp;9h$k~s$voBzoWH-@qW@21aPFvz@NyCJ z>dhI*=R^#zgn((3*)9?1BE7Bc6tEN0WI9|zV`OHd6XOO|Qe>7{^hguPF_ z0-aJdKC&g?T0ghM5$wU&<>hofdX?p$CTX5PHQbX!e)lGVx$~=)TR|9e0Hi-)H2s&y zjK1s*$hJ0QiHKgpy0D=AtBWqHLTJ9+$=u#SI4j*plwn>A*B1@qrl~U5;wQC z&t{sZLtsli%2fZV8>&lK1N&aP*SSkkJRsQ5kKDtJoy*?nM+#fs7Xs~MDDj&pyb-to z*qiN{`DccKy&1<*E|Fti@jAfWd&dHW`YC^;HVdl z+r)6hR^R&$gm_W%=Zj<&z778QLE;Y!eA#{SQEjRvg5-0M!jJ+Xt;el7+XfQG7Ob|8 zp!H7v;Bf zVBmgXGzjpuvqvP_vhPAH_TiQZH|Pl~Q^lU!X*jmj@4rqgRXL@u#X*4f&2;B!;Gx=5 zhNDf82XpJy84Est`YGx!sP6FmpYg#-q0XQd63k|6YXC(`ag0)?$>F~YZllXnpsoR` zyS>h_w`4>(L*|OUPHXOl+EU+ZM0{zmSizs{)f&}-{72-0w->t>F9M&dHCJq+XNwd! zWrAV_(Q{OMFDEH3H2A{Q_z;St&#WHoEHh4RTHTaItzN7$MK!JzWe^23SiWpILl7xw z4y+`}&jc}kFP|lWTePYa21Vik!AMoc!F#dq>7f@KAPpm~NQ+JehO3}!Nvl11^Fx3{ zn5L9$U0hH`t{!NicSbd{!-;e~dKVM_l#mB2n)jBVTPnBsD5zM9$(RLvb%a~$x3pUhlFveAQTsfSx(Ty%%oEr6-f z=?uBHu{BzTb9yYF?Cjs(rdSP&%;}7E<~9cbxZB=gd8*F!>{liUr;DO&U5vcbztLO;6l+Tb0qBodazWX~rI^`dTSw-f$*p+uG1id0n)M z+>|kjoPmW81Z44xbAwk}{(V1Z2Dr6(4ebZ_kk!EW=Wk^+(u)w)!7hGgFJM4~F2Q@^DIdp%52!)FgG zxrpr%uavHtB+IrhFN}|7ecp z)i_~g=4Z^X^vH4Wer#;J)HI_)K%_+Qx5PIWhs%$>;X_?G+A~sR_k06Fi9p7?>9G2X zEk6r6?}v%^nPC|<0_ivNG2!*07CAwy9CnetZSsz?5Aeg&CIy$b=e-dy{TGGWWi>z? z>G$7q0`Z&<8>_iY;4R%&F>@GSYf;)Nj@r@)6N{?)wVdYkYYOA^r#n#|Xp|hQdywjr z;ESi?eJl-0G%575#47#hOSm<4$(((Rcm-0&AKTB!AJ&qfe61JJ8UZ%x3>gg%C`}R} z{HBM>-n=7j3et?KrzIy<)2te@vn{Z{{mASW3i1i(nD6Kd!}ODi41kJ`Qvy#%V)#+S zh{)H29ml-v5B$%Q(2P1qdZJ7~o;*$D$8OD4uqKFD(TA;vYc+9_fIhw2F|zr&#Vppt z(~1(+4)|e7*1;vdJHCZV9`p@sbi;Q`msNu8pc&wCCAlH{Jp+0FCn*3_;<0IybmdNWeL%}$!otfqAf(L>s3Z48Oh1BXdL|ABs`*mt9!x5D*S9AxyY-XpNm!v$bc@FXlY!OX~ObE~Z@X={lA zmwfU2diLl)L(d<K930!>CGL!@^JgTuy#yzu5b7764irhezg8K8p}v%^VB1P6tv~Rrv%wm0XitYIAJ)*B`-A^-4X zwbVXyXXdVK(tQ~_Spi132XRRUdHOl~ETIL4sJYT;%Q-49TzZ5MFj9LyojfL*Oc**b zD`$W|A}4aO;t;e9G35V19{?JOH52)g-b;Hlf>IGUBj`o>6GZA6HwW^7Xjg}dbTLaj z*u}8~Ny2mn{f(4V$uM;cE(p0H?C^)rOk$II=hovZCdz7x ze0sO-y`~BI-BsFW4_G=Q2(?g`7Cx^0RvVni$STV50dO1Vq~_YPVWS{$FLII9J#*;8 z>DaLtKh-=KOg<$RY%Ik@OEGo%QdA`E3~`yGeSf920;M+$Kv@H+XDVyK;m2+D-f4hI z4!mqYdMaNJBxlhnPJw}^yG!O>K09ej$H5JO>4+67i}D=-Iya8*;@7564RHsvv%gbW z1}DKSw3*5LKFg-GXlGx-(U82r8YAQunZvFzNt-rIIY^=6D#}pyR~3zjH~pr4~<{6eoBjvg0Z09&7ZJ#CD+6uT6n1tVR*s8buJyy z0&_(>@-79^&$reM(tb*4AXFVR*y7TI<(3p6%P^sN&Ax7e*{Ksi`X{f* z)Q-XsF1XkUnozHwaR^cVFUqTy)$`i8jH?=(~Dw>Ll8tlx-F5h>~!i+)? zVhzg@DlVATav&@B;A=yw8c}Oh{I3fTz9zVh5r|pi=2yvX z?uYqNdc|}t`y50+P7z~j5Zuz0Pv2v4x!X0}?p7wWI;+gr1hdueN_FZX7a(GGv`Ipi z+cLnSpy%o==nY+wioONHIIyQI9sA+SY64tgPyW%Hr^Vv@WDi1YT`FR>^*bh02eT zcqw*Rlab?F#X1Z9wHn#Q{WgF5+WO4uK1Z?gW`MU>SeX{NpF4&4mNTbstR^22+I>{6 zkprnLrm6uMgHc}M9b-@iiVWXUPjH&*#y>(q@R3BDa?U*J+VQhS5=kk5ri-X36?Sz+sUYB9!S3C%4MxgH(yq#s& z=XE}#aOOi8o1LCH-wVCfCT7!+H8YI^;qH9=K+#2XA4=zQUf-K7v@ca?9xDcDEr!H2 zHaQ^>5Xn$Th*}Dmz7Z3I8g;*+fE_%At6U57WUPuJ6K%K`F4teI_J7%yjt_9KQ(k>CfnPbjIfC27^ z?rI=i)>Hd)8N1bs#Ny=suC1kW0#66jHvg}e|CFs?6+{jDE^R|^cmnag9~-f3?ZiHk z&2$vbiXip@6_Ps<60x<-HCBr_vOb{5VjgyTd<(qFsUv3L4=XXQ1@pTeKh`JUnj_F| zRd@&rYCFx_I)>)c6&=Ee2E0txeQv(L2Y3qc%#*`_)`mMC!Wf1emWvN z&mVR%z(dQ`cl#1-m8r>MLHmQbj_d#MRHjX3;UnGJk<)e!I-+9}fB1g`Dsp_DYExJs zSwrW7Py8t&IsgiT95J2z;AX=3!7smE8>%Gu%z6wK?DSPej$AYNxms)XIc^1?4C*R@ z+~9FW0Bo!C*Z6i5hNXJ_aG`CM@_jY@>ttQP|I4>5=en4t7f;}%7>X`~x`=VBw$tMmXH8?&CiK>}O-id8R+VY_GWLp0 zl?ts=*D!^|38$d)ZyJ}RO{SsHnvwzdDt}%lPS+OWiSbpz@x$~w^)oSOBC8>V+^mK+PG(tONab&F-jr#3v6{NXZ$|R%^ zl|Ne)S8N#XJXuNr1zr!Ww8zTgcMA#4ckEF-Gnj$rF4`!O3FWslE|dyBptWFVpeS9T ztLR8lR}v*4EPNSikvP0ZNhd=m zBB}>dOlc{staR>VqB(wxLE6gH7^S?CVmxczM0CTPLF%69*Rp7fPz)eV66`+o~dGiXa?LQUkXC z;(Y=y**6f?9=AZ|6%6pkY0qn%a?@Z{F_sUGw;BW-=QSZdcpcWZ?hb3R2(rMzWJH(Z z3Q>|nWs#(Rt#TiDOsz`CtAs~w=!w;ebDCAH1z{%VPl|^m=)+S&d17~~T;pYZ6@C-~ zcWb>PL?Z-MFYrk_qvYa~q)9afT_dy6$U-#aAT!0R<6A1Tk~ZgVLv07Gg|f?GpJrYE z=@?mun9hJ*JbMlstT@iXVXR-Tue`+&K3c#61IZLm7OL70Cj{MbkzvjPsyd+_P~9H3 z-=AHetVk`?q!}@iFPAd=5~!tFOwxO1VTHgMx*!6T39?c>o~0N~!=@3{Y)#Rlo!lZU z>vZlmb|oh4FVxVLnqsQ7e zk>rilTl}Mjx=mli{W^)P9VoWB>|56&Wt{L&J+GPWDuw#e#&>W+^NU>Y>&RE9 z`4Ti(P2}XNk_d)(;ETKf;oFGEd}wKG;|a2dtC99SOt@=x*sw%cOGE>=Z8IH>{8J9K zbgTU%dq{KJ#AJwno6ThveAUDD%BdRT*{(;Yxz0;*4nyw<7`5pZCObF;%Om$?XXs#O zKr8P%pt2Wq@JC#5@=8&q9;&LnwC2!ylI-GENtjNiM73S|I^e|2`S ziC?!r0F+J%@0$)WJXDS$kTAPrNZze91{c%~_phTm9o<&}3#*FJEUim-swPxFV3 z_T6COVXHMR+HLoWOvMYKsN+t;dBA)_u$!F?q$jA**KQ5(>HuB5whK3_*6k?Th5X22 z08F^jWjJX*ZC%dg-7_M1w-?Sl2Y@jVIRpyxI zyw{+Ib@Iw52{$C!=ZX#A`!NO}_C0ZT0TSc`;<>kM#tuoibHHQbER_Qao;c}5TtE_M zs>Ev^_p&7%_(v9L(C&OQV-v;Uuwfc2*y*S1o@2LDmehHkRkW9U_oW#-65$rJCGSlP zIX{FFB4#^P=64enLGeWgsksP{8p;>Uk8d?Twlb{th$cU6F+E8$6?eHnO8ewRHT{%6 z>G60(^~qVJmV=@`UT(rP%3L@CrV9jZoz$(PA1z5LevW3{hqc6rCrzAv0y#VR*MfF- zE>X1kwF35Ol$^s|0llgO!U@FbQXxX4&BOI`Cu&wLXfvmFdr$_zz(p|E8-x$YS$Gn& z`*uzAU(?>_0JFCSG%R--UIoL@%~+Pv5aB@8n2(XO7IQ5+ckC%*N1Ki8!Uy!Z^7pJo z@eanf#yoiC6CPHlC9E^K8D?rQ z*xn!BObNcyCph>iT1bhtMxM-3qEQeHvd`&jgDegNg^ps3)Q9KcNDd5hB||g8=fU_p>&|Z`uwbY*HV-Sk@;cSa}no0S6<^kp`YG zVFwV5FjMU}>b8uR>4Mpfs+sb{kQi;gZL7&>0_g5I6{7DEj3~OVBR-#)8obN*t{=to zuYvIKtp-Z_Eic^~b~K^W7ZrY~U$^wilb-H?q`wmLb~zAS)d(5WB$TqV$WUo6lr^$) z!l4kutDv3}ti0%3or<&6N@9tZj$G8dSB^-v`RQolTwdgzH$E6xQz&<}0>Rn&uE-le z-9w{)uZ`R4$mH=~w6*AsT$T*J4=0;t90>=L90L8QlPfk~!@20Wbo`s{ZjT-XF9)mg zUMpvh4YZAc3J!O%{iz>qP%ipOEoHeuk5aMG+YgLr3@{Lj&!(hD%(^UnT=#F)1(%o` zAcR9G7;uRs4>mHgW-Z;26qKgEC`R`#Dyj0%nr0rw($=MEUWYY`X) z^s9L25YF}ZupdUd>ExjhH%i@@`XGi=%$vX&Ac#Azi?qI)2sDNgc8_RQD*bg{(|ya0 z#1*_qX9G8}He^XZw5+BqF*_-HfJ*q@Koz>wsOSbF%ru4oddIXKK+#!=h{#uRAL3c? z6=Bv25a7rtrq;Gy#5h3$LAd_cSC?r5K@|*>L{tE@iYQ3W5JJ-3%lvc8n4;GO(fMkW z&Cb(TwZI#;^mrIg*}jt-;GfW^lYGiLS>)LNWcF|eM;=3!UYIf&0ENiYry`J21p~;Z zYS%$PvU)d*e3WWw6-sGRY0#Z?VVa;S7iIl559^_HYC(AF1^F_kVx{n1iQHz<0(O@y z^1C~Na6}YTq>8KmwjN{~JjS{Sk~C zx7RgNNX_P4C8QIfYr%C|G`}8vZdT>;d6l}5qpnfEH)zGR8w(RBlZlP`Z{V3Ji;5C) zs=5A@6-Ydp`5_&7okf2aA=$6nr}>cRHz!!trJSZ1IS3UyH`h=C-EZmW9?Y#WTlE7c zZV%IdKFmM9kARb+w+=^+0DE>+ZPgra@>!2aoC5KV%c6J~eXNa#J54~3Gc4vFDtXr3 zeCSZ?A~b<{6yPz|0!I1hY^3I`s19kGNF|A{M*PkkpAaB6@M4PF$0RnadTB}O&#YXZ z?<<3iAMHAY7pWyS-XL*tReLY%=2L_@ceg2<)z_einzJ%7T!R-)QvELtTh+u-HSk2` z)aNsm`a6#zT0z{{pmf8vSCFa87Fc_$?7X2%7weo~oIb7D!bw6GOT-|@$J6uG#!Bny zQ0;@7jQiDhb8Sw!6Yf+pXYkK3;3sG>vNM&iBVWSGo`;rpP#;dEaTVHhiET}T`J`OJ zpUNg=5wLWmNiKkgM`=)~2XAm4aT0nsmT2%nrCu}v*(A73TBI}d$Op*CJ6X&NcFQwL zHKwP~T)82R%1+`60!a-kPg3;(!qt#0TXe$p*w(vmqD*m#ta+yPp!o%jWvHkpnfI3H z4jGr|Cg5N3TZ+7XuuMf=BfXKZ;A5?~M4s|nY)%5#7t;Bi*+KG2m}B=NuCe!PuXjo( z(f0m+X}E|{?&Lpv7f-nL+C!k&2-}{cd1#H>d;Yv&PNS9{_I9c;G3K{Z6>{j| z`qH9iNOj$6ElRTLKiaE9g94@wmYRlSf4ZsgM8?6cCtE`cD9Zdxk%}enm??#<8(no` zn?iXQFRLDG?kZe1A3brBs-;89BbsEN`giyrxp0U9J?@LKN#e9=0V0AeE=RHcVH!7X z5Y1+UnVVjOw=#fj_iFc-V##9R1Sk9^f{-z^35KfKse`T|MZ0!M))?B~J=}v{68JGi z-8@Ut(CO+@9L=qvsVig*6aXCrbQQ5p%HwX0n2~B&AA+h-`Qc5hIDJTR9V^)PzOI(( zsdk5;=xG7tU||qR`t`w(apW5pyquxTRt5A!s zZ7pEx(Bz)GlY3>yQ66tAsyDJ3ObD4g$+!@}eBE9?P{oP(UsSa-Mwu)4)o#q_`HFB} z?)EJhsuk#SC!dWSg`*1v-h@i0Dqx#$A@wb?8ghPWq<|eVkE*p+Ms5iDzy|}OpNB-Lz zfW#>&CN%PzQI8JU_lFPLLlZZRhUxP%=UO{u%mCByfT>OcNwaNsp|Tk#Y`4b})kiKHw2YvDga!N51q?TYVa>O54(w%KU^w;9@+tY2ID- z;Y#W@GpT=Gj=nhDYMzdgwNXp=Ba3$HijSHG>`%#y^9@haLhaeoA9DOUc0WzMruMh& ztRItH=&7EY;I|RBe?tJ=SOj#lnt-+`2;Aa5j@{!-!ipk$yA z(cmpoB5cK1B$&o2zKO3oGdMoj>98{k5f(3&xx4Q9M6W|WYNp-|2riK=;p3N+S4UPv zptRqD0K~lv=adf5Nu>>MWYf5O(k$T#l%(8pND@=*T+8d&4Mb)5{>8mqY#q^8tK!Rd zbHT9;+P8I)v=6kJl5+9ZNtNVQpj2U1D~clt87da^G;a}7T11&wi7|Ndjmex6_uJOF zE`MnFl;asLLYR;F4=T#7vF{d{e5g=_uofSetrxs7S#O}o9u`xqARBUEzhoUxPcs#($Cfz%p^m7Ezev?*i=k)3{S z#nea)6*}@E_2D-U0zv97<(r$R7k!Rbh4mQLy!W)zLGm;l4Jj`Z=bR;1<-s;FsYmAd zPkaxE0@{BS%z_k|WlA9`QB%{IJPQ_sq7$*^vLffF=D03j^?(=PvRe8;%oAJ3$~>gc z0KfXu666)VYwg5e+X)rL@T|yyM$n9VSbJ#HJx4x_Y_kS`*yYTRdsG66Z4ke&Eps`k@Q5Nd-T#-@k z!#YJeX$YyWTBgI=`5(Ld+MYMGPDx+E&zy&n68W(#Sub}j8NLG*gQsDmMUv&Ml-<1A zn_z>ZIT;AJz~V{LY67MamE?3{pWDIlNCda+kH&Jk;OUk1eyDOg!!3t=ZjP+?OC9uV ziYj3u6l}L{F1LX(pgo|x{8=D4<+dS!HbpBe=hFZq)S{BxIpMdNiAfUXmmllZNQw zd)>LNAQl9Zab<8od;ut2K(;wasTuuzZHDmA)=8hxc`?!uQY(_m~<}O=r*dEo-c{B4}#iF zmL3v)zPIZ2xM;9}DrTkHS~|{2^xRjb;IH~8ws^#*GsB)cfr#fgb-6L3b!&~KCH?RxwNYQIhDkVdVJviZTSsZqF@m37>M=zPOaXcYj$% zwrbFmdK>oPEjABa&71X*&mGe*m45g_W(2KaCS2f85xsQ31+c$7j`R~t+$>AiyhK1W zH{UVJ`^vq8-Ehs^+BAX(x(jR!ApH=5glBuPbBOa?(|Du5_58|kxL5OSzVCN6{uJ3-9BM7oI~iOxpI#pe+95!dTP&`xTAB57UEd&9c%V-!Cb z>1(iX#p3(+905)fQi^i&FL(I!#FK6H~#QI$T&Vpl_ zHBo)94rp>+-@$hMEvAZDJMzpGW`Q~w0kytXr1Z7#NIs6D)Y86)z;d=u+7QRSqc(*W z?WT%!FNsL%##~lo0H`QfL%{1*ZUSkJd8?t07m4t=de4{@dEY)JVw6{O!vj*qvP*W% zA*cW_HY5Q%8J{~;eLBk+`zB*=BjT*p|8HvaXY<|rKh+t1(8i5ia3OO2RFY z`gun#Lv*sl7sMHg2{`M50QEoMw+UaiCBG-Lb$tdfA2M@KseZ=YzR}85*vl`zo=TZ0 zulsk+cSPWY0>Ul$uAJ(?6*3gn|J9`U6lRP{e0T6bN*IlkpC0f99C||5-9&d83vBpt zZ)m>?dyLQUJYv+9gT=iDOOY!|`*Z0=x`Q3#ZI%}c(<_fld9TfmTYYBljvbWJ7hbx} z#Ur0g_O1`GX}ZG|73>pABYJ_@1(b=`MNrGq;y8fM7%wz7-c ziVL6!K9w1`h)}eec*9Q6oXRMquBhBN(_J2fr&#rb#EcfkSU2cSZr!LZxr*nj1r3Bn*Y0 z9O2%=;LIN?d;J^S$E75lzuXnWLcSaA8@}D#gr^zQKSq2oIaZ*LymxiNPE^1c+vKS# zTr6ex9I=~kt72f!9{gd~%E2=zmIuKMbaet#!>>^f4i?I77WcWz!$5B@MbmZ|pCIV7 zi+W5%ufBkn=B*c{4mrHBLjbL9=FM+?86??mI4_5%j=byrh8yp@3c#0p%;fqU3_4}R z4Q$&;*S@32X`6=}^AbS7G)iv4qa!uj@?yps;jIId9Z&lN{c~{eS6Qj0v<`G{jGi5E zzQ`o&X}d-bzWzaxJxTCp5_>I?nB|m)eJ4a+EaskDR%7-ILBn|(ynMZkHe@M-RJ_zA zxwA{K8#(ZoVem3q(cXLbThLYz+d=6mnFBehpg{JIYy9<86_uebAx5|YXKFFC;LoVF zYM>khrSwDfAP#CBr@D<`YD-R)g7>F~QHUN|i@HejV5KR=k_#kQsWzlTxk71A`C4*UgR_fO zekB*J&g?0VR+tBIuS+^Cz8s|}@-gre*U;ndL}!lZ{q^;5&BZ^dRwL__Nji6My3sDU zwn`c?4D;3yn-h?x;Rz3s5phwsty$Lb;s$dndt@OE82RDpw^@&I-_?j+aArP`W36QR z{`WF9MY(eR`cg$SyMOjmIm>*<-x`?SjkfdolT-fKwJ_=Ap0(UAj7I4my5QtR0rFp* zCtJ@;kzg~$)|JrM)pJGhA7r;1Hy?ke@6`o|?=;vH+<7G{eMn-o(AxGg-&PRhkejV6 z9K++}1=2t%n0gdSSpK)BiIN*GM-|VZJxaZxPj{K4m2jm|w5PX07^NawrOH-7#QqaN|8OPL|_I zv5*FDf;1%>ygLaCqZ^3L^Jlt=O$es-teEXIWX~$vGeO8cp~J{p*r`V>y4^-HS2)WT zv-%zi5KKu4gRAn=t6j;7sgI^Y@~M>*ENhP5f9W8?GT@8qDQ(#bnJv}&7|TUsZd(Ii zOh?PfZ9>Ytp5~`;t5JKcTj2zv9iiTX{HAV?SAuJj^NCw(d<{FtDl#kjBvr!3_VIUG zR|gBOYrpnHxJDInl_bV;jUQlZ5y-vP(cRe#!a%<)g6$J8H&YveMml9Ih&0~>Al{~Y zN4MvIPo5z0P7FW@BgUN{&>8Qnq1q#4KT8j7x5i;N4cl4M(~yLyfO z$`S+&Ht1|!p7F6+qb~9bLmR6cSn`&dV+aS47|>0w<}GS=>G{)O3|JTif`$Cc@1mwUOh1X+YFsZ6!A^ru9dD2 z0$bGAnz}04mdA3n7Nq*snJZ?}-%rOAsUVIPzcR{VIGkBWm4?^@^~*zh;B*SdiAz%Y z#`!=nIa7~n{-fE9kdYGW5=rOr5p4$DU<&7`2cUC^6b*YxCRI@OSSXtvJTf#?HtJPV zWMN0iU}2!fxFqlc6wF$DxeOu4hR@)lc_?>a7-Uj1FK`Q}`y}b~^9S1?a_N-Ho8&-b zz}Z&Lq4N(HX$)RCMmJG5s!m!3Z2Hg%Lom!|7bz}q2{K|J^P>|1Qu5chDiMgYmte>6~T6+=a&V>3a>0`@u}Li|_kjFtCXhn8J>TVa)J_Ooi_AdT1;o)eG)< z{vMfTA$hfvK3p`Q(?h$at-6#%kDYg#QFZ{2emDL^zh6EbRpa z9mtS6!BbOt56GO?B0azcqng^Nn_A>AdacY@j-x=ZWUFcUJ@>I(*+zn1V4| z^ImK_$ContUI-%CIj@rm)$?Pto$xOmZvwpgPSSt`tNHG7oc{{~IlGZXvUl&g4BLvO zRN+i*Qv_+SN5&kXr9dc&_R!`(&0qL(zr$u$>mJl@;J9z^#(P8am;PRmp5;tzi0Jj% zSL563W>!LkA}=p|m~`?Ch{Kj8)K8+kW81Eia#}Cr!|G72~tT(l1$puDO zy@Onh|L3SM%-agE1z#H=x+Zy47Tyl2K7{&d-1Zv-g5*m)oSJHzb}q3uxF>CwNl`ze zz>|Z|P>bt`z>9z)KM7_aladXpnG{<9%SeAFJ!whPV$Q=JjY2cI0WI|ei$Q8{*au^d z`hb}2<5gMuakWhtqlGlzy2dfM+&6`~@3_p=wy%q0;>cgN#M0lW$M$en%E=@eHBa#ttan- z|90T%>>Nw!wz1(xcfi5eae#MO8xEQZlVZc1$WiE>KpZKHSdX1wiw|`|Eg4Y zm+XiV6|lY3WzVQgEaega+*@;cvppVdE=N$(FT}iHWI?BufENsT-mRe|JHncLE17a` zcVNz*brsdE-kKcX%%_Zg!?~d&h)*8`v~4u$s;$vSX_g9Z#fbE`#mZQ?zaChrX^B1l zc#a8gJ@~*5z$~u6y`E{$L*)W0ry4V4Gx}-a99*c_RD3UF^eh>HtLGKzByi3jDQj8X zj^XK2n(I)F;-|k|LnzJ_J2oRi=m(1|EU6xhLRj!pr?Zj4e%AZ5TjRMVh|JU!(mQo- z7)UniH08^hoDLnJ=P7ia6Ai{kUz#oyE= zOAIRmID|&JZGQ{$9Ds`mF4UIg*V45ThnxfB&1$HJLxih{OHwPySVZ%zL1r4bvgJ4P zVPX?BF+7eE-%klDnQ5H7jJ5Ibh>t(-9h~itiSYG-BtCMEl)=w%wGjMT?uY`L_Vnow@iyO1y7RNfmjVmPNm9y(7dfQkEl+ zNKdO2={**J`KLIX9C@=_Mqt;0&IN|tct%vLk@Pn-@dbY!*6?cpPoPqQo^tYfHKPPZ zB&$m0?)Bd9VxA80=V^FPlC9gw$IC`kH>S_$$O^Ti23u7a=Ij`a@Yrr(Mg|v>(bt`z zXD@IC>MT^5gL5PXgWKy@36UcmsYXzXE%}-e>Cu3{0*>-2HFZPB)7Y3x9b?88;w6WH zBeC`10Mm?uD!|FyX`A#&sLTJSRlsF!Q0o{5er<9#t;bwwaGC#m zLo3E^KLl{Vcj5bwP8|lI+Y+|GtGlvt5|E`PQ-q;XJ=N+%CE2x*9+&Hp;E;@FDh2 z1JN=%=>BAnNE~QO9~tgI+_~;kAq6nbRLv4&D~S3;JjK4#s0#Y%b3e1>u9Y%{|rNtoQk}{yntec~0sc z|K0qak#>|`?5Z8pyggHmPw60Oj|YOG>kzL5kT1kj_K2=bMK&4QV?xGI0!a-0jSM`z zmR2BcVLsZFDYCT+?UGgFf23EL7ogboKH*A*pOl%9ElT58>e4CFR8pG&ms>6mIjgpW zmDwO1<7Q;~>W@XgBFXVhfPO0Qp$eJ6Ycun}xNw$pe6MrE`X-DjXEjl`E_R{;?z7qy zPr~}8XO90vA$~j0Fa77y^K5ZR>}=43`t2gPSum>t`Lwt1w2@yYXv|p9K)|12VvELb ze2F1O`T$iL7~yW8tF-({bvu2CJrG9dMk0-nrE&&fzYFh^e&d=V;oO z6XDFcPlk;S{65^Qp@q|%QszihPLgN$+@#*YV*OJ&^1pA{4U4P92VLay)}#iv==_RG zpeWU99UzO2<|jXhp8)gK8o7CC?whPF#bj zQnTZ*m6#=cu||BV?fEqj%ynP=p3jZ|Jj&Aaay49w3~dB$KzAse7jh44x!yGVj}p7- zJOHV#cBY{YAWWV+cf~zA1P)D`j;9;jlQ-*Z;8aqkkS+?>(pj@$)3!-6U^1cXYMm{^ zB~O=|waNwUZI!M^ss#f)*nr?*0l_(o9rY!;*#xuP z-JEPF4`G0l)Kf9+r6E*j79q0}&7P zeFp!LY|X?y2|;wg)@i|SB&TIJGeZuKR@9w+C!=UeTF1HlDK1C z3dNuBB39o868(>DSg>S>G)Cn05=?W(Zv6=y`Tq#S4>j9$<1@)+TZ$Qx4r!4g-8T$Z zEi#9TZr>v#m2z9H?kSy3;`^TH7i=;0y55#&V%`1AJn3jhu=HVo!>qe;9Qp;;cgnB2 znNSX`L1QIp@Lp4p^pxDyIdTt}_I#R;T}<#zG8|e09r&0%zz}_MhUws!P`uiJkAF+VhNb?(e`)2C# z{&DVQtn}rCKpo6=W@d0`OyL)XjLuqPnQ@8s)sVNtG{o_I3P?P9h+m;tc$3Ga_F2j{zkweaG>f`h=2Ez7VQ*ihv2-0 zzx|~5u22w-XUjK#qm<){LIh|QpW#1FE6RI`dHBo-P1=}nq3^DiWzk*`C4W(Di>L?4 zgg3|nb{v;tm4FxEPFMvFJH&$ZH4Sl*?yIvzxjMrWCO>}x^`xosz@b0$mjqS0j%?Ua zk^nbZf7b?Y|4l7&2d<=W%;9{H8@$O8*bN78WS%4dq~o1v3tb5W^nj}_Gqli4Iu7e2c5Gk z%k$%R79T`Sqrwh`W$UL@I=-;EA7~`~1ogN1W@S-J==+^XtbI?WJW2t%nt*oT?)oi; zCDu1A)tLh6H^ym!wM|w{8ocp05afSgZ8BfBAUbHod*)TInL!1Gp zf#xup=O1mV2rydDqqDdX3p+27MW+RVL1C4NlI|jmX_T)+NDDS8HKsJr$mea#YX|G5 zNeKqb*;DlZxyVgM;X*1sq+;GAAIU_20#90q%8q#n4iDIJ8o z$}Tdd5cvD*sU$xNvz{9qg-^|d{p;OC9+=R$SBUDXw}d4&wKDfS5tZa^wKui&=9MN z#3i`hO2TOd+;^mnP4*GzdAtWCBk)b)Ss+JmsbCHyc_01KUq+xTr>^$icEdLmR_3F_ zpU!eyZ3et*8Z(++=*^8!Fxht4Kps?xv;Igx^X$ASC)R0Sek%Pbm%0LN4>zx5p)qO^ zfP9Vb2+Da@iKAsPg`l17?aQtMzu_qWRM8XU7ghApp_o8TtUQrro2c!B19}Y+2?pC$ z)l|IlF!N%Av$T8?S`$$qh5Q{nU)da}9jf59GLY5F(B}EvFo}T^0Xr^UoC36I@})8Q z_Vq{lVcwS3xvtW491qYt;3MF?yZIv8*_qF=;QQt(Uj*pR8)9>F^cZkge;#{Sa*~l-bG;KAvv|E z7B23MT!@(&+Wm_m^3L;sgt>uu2>ACC3l)P;&nF8T#9HR9L~+&P+gRYp&t9oa4vqao zghTfZT$+T>Vm8(-^rEkpa3|ZbDX}}#yf?L+wp!F>eq}|yPoD6EmVRoMttR=q*r>aN zi5^CP3(s~KH=MW-#QdFv@Vk|>pu<3zMqDOQ938GW!RmwwF(x2_wW~UKv$g5jc zP?6O|81|M_e$cEp5O-ld#2V*=wlGRjJ~P}Lm<+d z28fElbWcJAUQoAe`fXwOt}R@Uz>BOBMi2gn<=<$lahV>q7>U3S5jW+~tdMrp-OFF1 zaIRNj9?EN8vJ_$%A)HROsK3tLn3reR@a8YCXBWg3(dK{*NTdl+KSK|-7dQWO^gb4G zY;jBp;0c1KZ;dB4!obmcAuIUZ!@lMtFhoudyKG_H?|Lvr#@DDA5}Fd|1-}*St<$qP zB-ij~*3eDPl^T+onjRbVI#N0_KT!OC9oSYh_8Xz;6a156B3Y^&JL36r*9VA6>4?2U z8=Jp1T&(X>{}!2rCE!u4UPr|z`zFjq#leZ{%M3^y{gl~;?K{zW6U68>f*DosLaHr? zYFcEtaxA8(qh@?*9eq*!qh7$LMYktF9+My9B^g{ znCd=KaG5>Fn{*@&=db>n_+8-$$WX+TrXKmT>Ak3un-ih9rld5x z4*+9UQ!K|nf%~{+B2vCMa>%VW)feXD@M{BL8(OVru4e}o%FGkaZ{Ij!o4mt|CfY&Z zy*fV!!OESWe}SYFx-c);4t=bb(=GsONWRnHz5_*ft%(fk-6eTZ-YLN)zK&--;gQ&D zbB9h?3dPz$jTD_W#K^lJa1>vhU2B{M1{h*%O`Dp+6~ae{HfuFRT+hB0#M>a$VJ({z zLm9rZWy~uW@WHm8_b`$RK9&uhVBTp$^6kgCrh~aH*ic}i@wxhm=(@Lu9ECY zCjtia4S`d4;*@TR(HbYe0^i0D=R1WA8Qa6?+tO23>1#2+yrOSF=!-V61?BI(_uX1% zN$zUos+s~ff^#9U}`ev+W1&FpI79A3+d=(8h z)qQ)+W~IzLeus&R@93xYm#R~~Op+Gx-$VxH<`GF#xC0h7!x9?iDe`_>tc>`UaWG;3 zhBV|XHuDmMCKz#$I%gq)=y6E3(AvQ?)KlmW9vK)d|`s8Zi{FyrA&NGm}wn)^W>kh|RZEkIQcv zSoiz(Fh0u0U0;+2V&Zp6ohG9~ zAuW0-fdMI?T)o%HT+O)!56;1zUno);xrk)KV@N0ZB5Eo&(`YujDO6|zihRd^T?Y8;qxZ5lPLlUt~Rn)ihAva zbgkdZG#0wyTSoHVRcELJ3zvGxHU&HgBY0-dg#NXCYmIpB9b@R~j%|tMf4693Rd=zd z#7PQ-OUC;03QNxC-cwosWLzud=(>f$q8xHaciIH&a)^?#ZlLG+-T|XLf1lsC+SX!NZ>&}z2IREl<(KN zk7df~*Zck_K~W>(UOMTmgs8yI>z4$HJ&9FEBZBP2BQOcV#|~!5FkCSRI{xr9&ZSc5 zckGtmk*ifOW6tOm6}ij&K7SDt3CdGXO*Ptj!UrJ}GiT+Hn=+%?YDY`I5e@fbK(JE%y5AswJ9{vtuYWnj+y5t`xYB74XX@nyZ^o+dVG8QSz7F7@Ps@~1+ zgC?Mes(3tMzgfv8#KJI978|4PJs>B7efb}YJ5s!z+Z)L=t5o*4#hlfdGe8ShgC><|F1bCwu^ zn8VEP2{u5zDDYOS8Rr>Y2kc??o_%^4m?q`eqRB8a-meU!1!3$QtV9C zQR)f049M`kk4qsE$97jqc4kMCo#blQ7IXftUQ?-mUob&nWZV=76IuI%PC0-#e-X59 ze2NO_VA|9Vh!Fa$u??IgT3ma+;F#R>zzgBbI1A5b8}Mxy3TPg67YTq)JGWIh%#fHb z-psgWNPFLBMR{Zoi5qzpt?dN0@<$Ix>ok`l;aji!m_WBcIaF6FmkyCCGQai;68fFh z-t2tmchZ~vUY@D!3T;`D;HokMX;1DIrvJhZKe8IqfV7p8>#R7p#N()=(+%m=;*L%N zi&_R}3*T;w43bmpjZa>7sU%@ zJiYtx!5=)ssw@{Df~V=yJPn{e)hdu-;Ncjy*V?e#bFjFT`DC56ElB7DW#dUd6~`~q zuf0R(aiCtkwU)X5) zCjK>JoV|E=XrhVMreIlW2D3B^p;{jbBTM5%L z)w)v;zyl2?VV>DODWTy4b)u?Q4yoJ(cc5J7_LmNki&-BzLsB9Xi9Oa#*T;hg30wCz zgJE0WLnWGR=6~Sk#gN&~7ZFUH2#x1?mLb~e$={#H^Ac2u15$s20w?#S5+v;2$C{;k zx+!$FV}T#IkO22+?W*~UJR$^p{}GqI{d+_-YD1!AdjVDfkDzI1Zz4u@Pf@D_stmz8 z(*Z6vcpwRmN$T-qcX~d+5-W)2;VI8I$*5rO@?k8YcfIuvI##SEB>9MI7;7y?t3Z|q zyJ-mXUf2i;+}yMvC#!x8$Hbu8+)HhsrqF%%U2Aq}V_d~$&NqSHjpUY>Q=zEhO{OK& zd9-U@15$Gu^1N(xA0m61DD9kE!MkZWj+08>e9bsccM;?Dhr`au#v_1~2Cp z`$XYrw#Q*kS#s6dUD7@GR7s1hN6RfK^g<#DufsqdL*%{qrOY#6L6Ye=&0vS_fTqjQ z^W+}RE2Nq#OvoRUNv%d5BqLlST=wB+v!P4dp!PmsUNZmV&{TRk8N4Q?P6D78^V;Qp zm2pFZtN_Ze4XC7wE~9e|`=hredPwa5#g%AB?Qo6n=S9ofo$98zV_O*DGcZo5ftj?> zzz6|s_tD3ZhDGQ!{FqP?ChcRRBTjeQ`_ih?C5E0y59#mOM|j_ zvHg;sK0>e5=0x|m-N#v42j@r0PXliwn{4`P-bC{8a8_7ZO0hc(6z%ZK2V+WtV6Bbd z-&AV>alJnB>@9-NdovBaZ7uLDPPu-wn8t`}#l`)2J4>f7`CK&}EVq3ic&K%6T`sZK z65wNJx)Ar+WT%qMN#4qU%||wvN<`*fT3LvxLbH+KkVJrj;b3^iuERo`UUiRpiNrpu zS3Q(eK;5>3hZe@$<1&^_N$8i5_|X`HD-PV3z2A$aVtt>c>~P#eF=hb^6F`VD%t%yiOu|k`7O(3XcM$=en3c-7-6%A*5do4{^1#0fqU-e zoggJh_G>1$XM4&=wHT6*pjjvbp>K7O^ysc{+PHYb3lHu|Hp+A3 z!Hq^}+deFm^NF+N^mnJ^euIG7y-_%hB$4!2+~!D3<{Z0q0FdVBfNE@Y#nIaCh2@E%R( z@lP_89atqBMplDK z+>hunItfR=Y!K&yUM}wCLrXm;DqT*Ue!^>Hda;X3|rUNpZ!BK z`}I0+C3tGieRvykSS&g5N`Z1nL*S|?cCw-_VjvzR+XBc|Jk5dL#&VM0(<=nFFE&6f zshVR;bF9*al4-zuL8R>=^k!pm!7&3_+jt}-iQ>@+p0{A*2S}6e0zcv;L#Q*I8C)4~ z*TS+`SVw6Joxvv_kO9FVAk(&*lT%T-i7}=)pqwu&$hB0*1rkJ7}|4- z{NEzJV9CUK#RutPuKot!A6y^|>=IG*n-Clj3|syTOQf2C|4q`#3Js#0v#(%1d~1ekE^pPJ!|4y)@?d*2W;@_uwSAYFrCQ1&U@&Ij$ie-EHty*qg75dA&1Fy# z{@mlp4ngl)pX?pE`%9~=B!;=)-{*l-AJP-sAb{)3L>GVV={(Ry-~FT?E<58u%)!p+ z{hLY2ayPrt>!5xT{HFfETLBRa&M&P6d7$k|a}(cQ5)jWlzLOv&rFjW>eb%w&oh-_P zZiPvLz05#4ISlRERQL#tfGz}^%7wPia%i3QO}#6N!q_Ox?rRBVCNo`w(#ZL;W81s0 ze6{^qPMplHReS=jI2|%=QGh&Z#i)Wvi8EE>iI|NO6x{pHcdDo`yx|gOjM@SGC6!fU zU^HVdWwLJ%>@Pu<&@FEh+n~Tg)%ff_zqlYPlv9S4(AtyMXolDDV?1IZ+V2yjS7JK` zxA)w9pslq8KR*#%8Z*{MlG#EiWc-FUtw-z0{i||tx;TYyU&K>Xcj(9h=6j~IH8HOd zAh5?HHP&V4{L6V=+tU!L6 zBV7t4BKjbFaJRU|nBl4WHiHj71$&BW^$2lX&?)9#$^Uj*P{uvg*r`QG3fYX7}C6LjxJ&RV^x{y{l(2^Cu$Ws ztlRS?)4)F#5Ny0U#E{+2%LZhAN|X{_f1+}qY9NMi^#%XsqKKH#dyPo`g4h->56vd# zygrufg`ME7UhsvzQy8T-28?I}r}ZWkm`yn=kb%mNeI;RtcW)kF?4$Ta!+}>!uOXZg zcsRR-jL-w2ITFi8%Qfk>whW;c{2d;@#2}MbHKNb?T%@UDHa$#bNjOyf`6Kg z9-6G@gW8~l)bYOLi`ehK31_Nspw6u0fM6Mc6ZHq~KH82wjG$jaBi)n^b?;#L|JeSW z9Q>2W+9Vb6+c=efK5<^&h^78$zfd=Fz+YIXd~W+?jy@L1^Gr(?^)R>t6D#M9dv&%Z zQ1J~R!PSUF@$!FbXcrO)J4kj}F~rv0*A4m|MY7W*fFOONzb>QJf z99rx|(W~2&s1#U&{3R!#-)Mpx+bANI$J;_*Wx3cSP2wk1JuSDI>CC0Mgb!*WnBN%{ z-7JTkt1&ig0a37sdTL)ey-syaVzQKaI27ZzFMyKuo$Hcl?&IX|QCi9k$Ap&^1PiVqq&eQ=1l6@D#)V0` z8yUnbj&WKQIhy`P^P6Ks#4@%k7?pOUN-9~uobwINOH}4B`02!EW7$hPc)QU8?Rnn^ zwncP~W+m=9<|A*YIGd!YD*m9U-d}>;^5|U?#j$Ihu6`qb*~l!bYbtgN zCOu<=+*@yisA-`EAgbM`3&B}{81I~xc*MT{Z!Z%$8PGq!C5&PoY$C8{HVqeeP6h_A z4GZb>8Wa6N@_e1CdwOX{s!!)&1BLj8Y1n90=yVPL9b#jksb9jh`fH`CJ1`~E^c+7; zm4~iNbtpdSx8Solq zue)OGKbIfZNej;!<~$|2XK;Ynr;Hbv$MX5Bq|*j7WGCgMQsGC%6lBD|_7U4xLCu(u z=sGDbJs{*X>WZ;%)VZ$_p6EtxVH3&TFpXrI_u4{Vk^M=Wzm_eM*Qmsfr-((GqQW56 zBM+3&ss_Vsv&`bq-*$R*HZZqy2JuDKgm{AwUSC-ASqDys1_a#z$ zYg&Ve^chbCu=UI)+vpizme>)|H;*_)i_zy+2bTaM?%Vzxx+`TUTw6 zzIj4PFGq^N$GwU?lqPFlDb>fv^C<21{W{}i>Fvvo(h@q!4Vo*O2l{rFjAgE~)aVB8 z_e7I-P-gGOH(Lf+k$1ZGx9MS6)y)8S%;aWbT(!!nOIuyCIiVQQnHw!Xrn5jaOS0Aj$!ft}fE8B}uDTDJyXcG|(>{ zvS^ry&XitAo_gl1O3pon;$zTFm;VnJrU_y_4PCLgs?t~8#{`SNh}4s6(~nG ztut~RD+ojkLtk@K?EaT?Le;hDZ5JV8#qh1`8)&h&yiYSg=<45XQlF3|Xe~Mne@Nu9 zCSW#wPJXaiRQB8ZQwS7jGH4%HbwW$H+M3isvnKKcqm{>G>(eH&wDWFs=`bZ>w-dE` zHk=p`Y=`S{7t`}0Tn#3sD9}NX7f>2iC0%eWq&7OuJ0^v{awMHL`{*0b)zYHGm9qHF z0mge6J>2Ad=QCM-MgJ2-eb+gci~k>2!(zHOZ=(&-yGl)XcM9q}F+ z*I9o?`5tYyH4f}C!RB#eh}w`QTeIOk6@fn^>Wvn2)sHrMW>lp{-gBhvyxS8`p0rpM zYWS{!)=!6uph({7`73%h*{+gew4h7Dk4nTD%M#vCJzX-s|MOj3;8S~hgM-GIWA~wE z9XjmHBZ}ri(6ls)i(&!DpGU=lpGDEHz?9j{KlVW*CpmLfE{e4{ax3%9+}_4Wgyf1{ zYHjy!o?#KpO{#aY803wm4hEFYDD*ci{ka2d?-_AZjO&qG`Fx5=6@h4|PvjAu{eqGw z;3Gi?6`_0)&0NQ05z$CM+~mNehFXTqNt6lT|AcVVB6G zOll!=H<1oUBhC8mS@P2a&4Rfe9}0W16j# zLnzs?k=zW1@K}J-MsPZU)FIZK?!eFat$L-UO7f)7L_f71kV@S>s+!f!AKe|q(1514 z+FTdt11LJhVVt(iHF;n$C$slxL88;Lqc?d%Bw zFe?85?B#s-Z(Eea^Wx19b1GknO!h6y=YtsB<$MZ&Gb|^bK@`Pad=B@Sm$;u@OomxhN8ajS|>Ke}ADH$IJb09@Zc-;86Ip6){9%6N>}3xNsw^^s~b)XqPnEgg{!-H(EP?%bSFh^BhHdvyic7LmX zJfM8!m5&OrKs;(HvppFEMHC(T$wCB`IM%w6(kX<5isj3@ zKi(nik#`XVqhz?48w6ca0z4hD?BXyzC&m{qhZzRGCZS)!LbeHPp3L6Rd7(z&E8zGB zMy#Lx8Voq$G_*)vC+`&WXOby#dKWdMdu>O;?N;~mcRbTAkwzOOZC+`)bax$eWlh0H z1g2N|RT6)df=ApTIq~RwE*X0x58la}1dkNp`o7yvVqBP0$%@9|`fWDYZ~(0zC&Akp z+znD{o_-AI$}$GT<%^)d&+m74dj}v}TkTBFv(12|VM&=Aj^aO$qSv#@a4jV-F+5=P5qBk*7vYHr|hUfT|s6iOmMF4h6=V>_o zhutT1h0AOHdXLwr?6`7~t`Q7RxfafSSgd80*5;STwRf)<0TxF#n?a6-Ad(qLR+v-n z5Pk)ItN_>ZIzV=JH6cP`;e+`$RDXh2bLd>hk4(x)|4{J6ELkSj+b7_E0rp-rVod+4 z_hg^?{=)SnPxr8DK@alTolsYU>qpLjH1+`PMl$3rZJQ~DTJ zkef#2dKm5D*bJw}>b;RLP+QwP*zSW&++R)y&wL-#lC#FN)-GbnvQw+K{!815=w+ff z@dg;%`>Ib@v(>I15gt~gK`rEPKl&!ZKVu4}D-znmbALEAGlbFpOZbZ*FW^bX(4JLf zEoT=i){+7=7r~t`<-WiuP&*W{)XV6mvyDCL6<+*qK=ps5o~a6zh{eHv#n!h!Sbc~C zZrQCXH*Cfzn=OqExM8M+7pwT}Lt!}?YFMcW@=rOHNTrhMB&&SZTd2OvyS@kmk8en| zbEcAuy#WaJ1L9m#1TWK+$Fc^Ly#0_kZoBSgD9(!tLntZq21qloZRd}k>xo=+O0SALSeY*@?z10E4AAs5P7u zbtNz8HRU~W@uXhg_n4y>X{Y{NdN6|=2)!6f z)4e!At$Gv8Aj!s8O;iUNBlktZvvN1|^xV#fi*B2n9Cvk}b*NF&<3be#*kVH!G1(Xa z!lt4FW>UbHnYRa)eumgv$h#I};Sn=KTSgkx8|B-@Hp=pWq5;Zl`RjX$WWoD&A@>rW zn7I>$9`pahsvD?bcNLc%Z{C_MpK=x?mz4*^-Qd-=3&zVS;J-n=Y7kzaYY)~Tv(btf ziN?|gS7I#?qf23}6Dl(AE`r5-adB^>E)3KPL?Sl{$p@gacs^TrI87aDz}T-~j;myn^dry8=u0wu?hv5wBBlFM*JBeFNWQb{6inj4xgJ*>5}ikS z-$_2Ei9>gIB(@x^zgzq+24?B5>RSZvWd_mk-8)wO0xlE zhW!tqmuvN)u)WgOzJyFU5Okn4D-{3L1AfsV2j9=uwg0`OKRJth+rLZgK_q4jfa>md z=YcOEqu4f_pthJz?DE2}vlY1Y?iImyeR|d*oy-kDHSrk_WOLce*bJ;Kp(MKdsfi@E8?N5T65IKJp4(!)}%4(M9!2FkSP%|L?~W%v4`96e;l3AyC1kU zz%a>wDB6jy;Pv4WYp4Ka2bJX9Jqlra{M9OgTnJz$-|^2h^Qmzh3;$1h^@vp;2wc78 z4#GBgbGx4$`miDZnR;)mN)J1Ut&KZ>q z`n4H0mF11Q)A4^%#aX0=CweQyDQj}#Y!6G4&Zw8tRay64Aq{&CJ(U9Wpbz#!H^3iDuddJ&Wq0apGvN34lG9SpfS zt8A+Os~}}aV5ag;z>jMVSQrsYv6BVTCdWIM$D=8)3567iIJ2?Su~+^_g@=9Vc?KhA zBLeZyNKXw5?JElv!RBdY5U$s7b*m)Kmh7zjpMruRv{P|lcX`c#OlaQIVIVVla4l=)@y5w(}n~hLmrsZ ztPx=QL$`X^K+imm(oK30FlFN6O^dMbs@qJ;sTahgptZ91%Z{8 zB6S1yajAYS{(9TyWVVJEuvq3UI$l1|33L6Pm+82;?kGZ=l!Uhqkz|;S#|vCJdyXE% zHnmnZKW;^11y2r5bdx_CY=eJvX*T+J4=Inv!5uo!>#|uAOje^*toU9@S`%7)bEIrO_>SB!(9qp-zzxftfRt!1lw~H zJOlQnk&7J_>+qXdP_06mB+I(r8f8@xlAG7qmczg32+62Ml$xhGDU+bQ6G@!b=(~op zG4UMo6O4D9640bslf~wxxc@}inPRD<0r6Up?+=-;RvSiM(mR$CG31l1Yg-l+g~c~z z7{E#{dm>ZlX!gMLxAPUvsbvhEk|ZtLG5%y#r23MowAJUR4afiGh=zL5!d)E%iw~|_ z4z^EMEIu@6?QzAja{KZbx9uWjMt0Ipp*d|Imp!0QKCjS> z+pPjy=j}%8jNXvQhYSPl!7?rWNdxEkjupUgs~WdrJ>lGGBf{6 z>l*vB(p?oRL2}>Y7x&_BlOz}df(%F+<%#@Cw zHqkLND>~g{qOf@liNjovz`heYH*AE(-|G)yeQ`qN{jbDb zN}PI3rprxa4x7zWYMC(Bg}{7?;u0$I0Dfa)DJ5x#Td|vG2KyRV&yq;sLQ?!GY*s^x zgpMmo2i+W)q(G4AG;~W((v1Ksf)7bq+^6lNP-)i)ASP? zM;G@AZAi8rmWPW$O<7dh$Uf;hgC#?V>~#^>{!+RkjW)q4>ObB9f=9FO>K-cXLWg6j zUc3>4tL!fePsi%*DT&UQe-Y4rG~kzp<{%PI^XV4tP(bGhHO)j7!Sg&SO)+Q92@LXZ z+^xQxOU;fvwhR5DF|z{WKso3X<`>}rN)q#|Hr2RjSw^Ysd1R#e&1 z4q`la3<_ZFUEMprcH%#?ySn?y-K#TV8m+jh<>?~bZullj$#Rx?FJej7B-0F`W%tCk zVBK&#ifHx37Tb~uwvILwldLe!hp_B3@oq5b{y3{$nC*rA`ifXO=a7{>ZOm@3 z0D8(mSc10U2kgd!3`GS=dFN%KXaEu)H+?a_+2_GSRDDy8so!OPbe;B&B+1@xn5xtp z@bBWCvnib37k%72&yf+2lgTHfZa2VQz;SCe%Mq3}5h?|Lm^>L!01bP%^77sd$tBDI z!~BRgOUdy|u?sKr^O<5M>HrdgB2Y&*}K`J93jC#3MPKf*e@Lv=oh#@U~sZ|TLesP6W3iilO_B~GRR z`$_R$=q8K#hHvX$co)Tun{QV#*eAl=c zHdK49`wS=^QpxeOy{`p{w!qE*VvTn(NP0T{7a|XIKw)cbK&+Y{#Jmr~#uwBOZ~9jnPvG zXdiI_%20z@ojgm{hh#a4>pqxdF7Pn&oi3wLrR>eCFct|W(9S%5DMX%gW1~rM?mm2x zf6hn=#@?ya)ItsWBwKczw?M*0^%b5_zxlBj95;vSE--<2PSGY2qFLB4jX+iznan!Q zYV-|B(fYUAT;I`dQfeHUewuU6rxR=52amS9FhceBU`VqVSm~p@n%w-(Ihy{cgzra1 z<{zk0xS?H^N|jWXgiz<&69FI$=$N{V6ZekE_@7%JN&WqWA0N7e&c~W9eUu;F>*Gl*=5m{1ynmbXy=BYSS4?#Kx`3!+v@ILxeP>m6i zo-hW{Ibf(Qpz(zI>N1^5c!J_3|6_PPQ{!|CeAFU*M~NH|+58`Ly;8o^z91!wVwxAPDz8IDkf5*GaH z;qIj*)ff(xS7jsDenGXOW!+frOTf3nk-QrUV~aLclEW>M{<%APV!k?wI?Ufc z{QhimHMCo$b8fsx)M+ zw^NJYot2^>uBvy5n7wNYu+gX&X6DH4F9)&g#s0sTI1(bzhiNHBi97wvYM!{b-2~rq zi^eoS+;f>ui=IO|IYbB4<`Q+h3?x(=%0ovzwMs+^8C&-UysbJwS6<@y&9%nFKBas|9*pH-Um(MEhJk_lMI)$y~#Ys z6jNjK`YTT$EMXG4fkXziABWf4sq2G@aK&Uer|G)Xe&Og#4xehbE@y+%h;oM5Te{IOvt8o*i6%g~pEL45_II+ktN3|kT(G?D91|u0> z?cuWdoky!mFYZbo6pMfJA=U}gzpmO#VmW9-mMSTPeM%7vP3rp=jw}fyawgqF8n~7& zxO0<%=FSS&IhcZLqC70J}KK{YR+y0pb*9?(|MBd9*DmK8sd->i^-T<=Jk~r;C$OCmq>9 zOj;oAKG;d*%*$bwvov$Btv^E$(p>lHtStKf;6>isxjj5c@@Z~@RiAO%Gvo~FAS52Z z0^_fDZ6&!u6*Qa7h6@5CACAj4%K%bA_Ljo&?8p2mmPG|=g^4S-yJL*zuA3xao{JOQ zC03N4CK>7rH@hr&0v!4F4k@|8TB!B}h1e#*xZZ{{D^*j0yQlS*<#z;jB+x&)*yFJK zliVZpMs&-~gBiwfuX4F*;^-MVoZlp8?7z}=6P=7mQG@Uu^EYYI76*3%HWKnZmw_;r zcKa3f4WTFmD?Xu_F`nLZ(~yq5S*M&yMo!cJ{%A@0?a`>LZVZ8dd2$I~jwstU3+|*x z^SwBD%#nokvNkDMqYhZMbx2~=ma1s$m_-a#2im8FE>#0&Q~pIuWmwW1jhT_lt{n@W za#kQ)S?@#p;Dyfrb8|s4+1KZ#0VM@a;76r_jUk`lbXhC3Xgg1>t*&MOg46joMfP?E z3~RWMMg=@5IuM?`KIjkl^L$tLl&FYw=1z&W;3v4k5P7s`Nm zm{IZJ%DLzCm5Z|-mlBdeU}u~@K}^!+(!$-7=%hs?Ow8xd&98KIng=^5NZp-KkLIkp z&YghbJ@YGJ0CYex$q}PO8EO0bk&%)O2Py;-M6Z0r&`sMpXpf{T4cQ}sEWZuMjL)`N zF5*X?X(?0?2BP6l*_+=`yP2+P@KYY5_UIXex9Fis2S!`PL|2IguxiEVK?YmO1&fry zh#iQQ@!?IpF2%chNs8LW|LdVIQTiZ=SG@c%jv>|mBg&G7zgBdNY_}$sm zs4s^!mM{$>XZG8Vl6GqltlMY#zv6wEk2@#jZaT{&|MLK8BlO%|2_qPN>W2d~1d|?9 z4aj__6Guj|Ng%id4A}Luw`KW!fitm_=JkkNnAokXcoXq#_Kx7`#(8!Vw#-Z>9qcXw z;se`0jXM3n)wL04YKh`lt%kepifeagjT`ggy$e6aqL|^g27`@5vI7P2n|7AE0VJL( z{8Yu(_oPhJ(|7M1Hs9z~a;rHGEM-|H@4iv)K;#&Fv+$4op{p48#*P%f_&;Ao6e!kE zf6CR?tCckR*BL9Yx2!SQa6-GvE#g3_S*2aYMPLQhJ_KCNLKnxepoYsh;W*)fVV>C0IY9+3M!m?9Y~Pf7~(xZ$|>D*%71 z0kW*4Cv&XtlnPBMhDKxx>Q-n*AVU9J&JNppy{_2TXc3*n7RUiZ(QRQchHMTryaCN! z761B4c4_JQ?3Qk1Fb>S~SK`~i%cOlFT&I7WAQSN;p4{f!YIH#9WY>M*Jm!}t|4s}( zCku{+9mLz{De$q9F?#%p*2tj2MB47VOHAfO%#@>ohD9?qkzW8A4ZD!R;sp8Z zLbB33a-TuiLOKo@6{X3f7NnjSaVs)ggLe|SsP*MSv4n0c6E+dh4GO4JfOI3n)uf~1)iJCwseKL&D)pXZ;FeRCu$YU+2R^d^hGbc1I z3f)<%BjR8>2rvI5ZnNL}CL^}>8h>)QIRrUG#9HncXR=H23|7KRLmA^6BDnBZBKy2C zhbvbX;f+*Id>rH@-J?HqAo!c-4q;0B1HP{(Pkz83*GRm83nHFLeEFN=JjQRA-J4+X z$r1@655r9aaLae47*+gm%!Xwq4RVX_J6gZirI=4g1rKwvAk2NjEl8FFUZP?7y8 zwDAlnDZRD3FiRe*kqlG~7{NJ3!%{uNK_b2_|yJ5uEXxq-*w(2`L zP)1U$^wF1NowJ?F8v519b>p7(-kC~Sd?;=xSDinRz;u630OkU1jZGq*V0KtJqOX++ zU{*x=qh!)=TfXHT{lR6-njU|rAz}B>ox0onxZcYiSQN6jR1cd=H29J@1t$nv{a?EYHje!Svg} zx1uiO8NYXJSz8gEnS8bVCVl`4rB~~JzjB@5M>wX&BEs~qLLNI*hM2#_s#+Rywz^PT z<)FVf&LI|^bl456iKq60c->PCT9hCAxJ&z#ZbZtnTeq-fYeAT-+xQK$tJ}Fk6~U9@ zmP`qfr4839nFq%)V#a{~f0T+pXvU%Ma<`+0n4OBY$s=`E~YmHMb5dwG@0c>b2?Xt;lSc4>Y$u*lN)3O-h1^Z2|g*kMyz$zYnd2 zb7{;j>EP#K6^OnbKF$88Z~``7hmcgUl3}wczCv%<_sXJYcdbCTIl&o2#bd0;4R-v24 zfWMF@uds?C=NX_Z&V9MfJ-oE8$?cwL@jJP*EuEjeFC9cF4m)Uj-prjW{ z^EGb{M<9CC5;BR7TsaLZ6WEZcP7qls*`$E`UI&ieyzTyHtZL#>$jRO2we)$-`2zb= z&@X>}M!Ys2@1mDE6hV@RHi<~(wT%QkguFq01Is;RY($1`?HPd5!6EoJ~DltXy4@xW!9Lg;wBP(mB@htXmhhu zG&nL}$wMo(lvS1@F;>d!Y#w>5i{!K_Q*T#7RpMfWA!sCraD1;xCL5C-`+*I^7xil} zn*~BB)v=s+OKQZ_0?02>q?~&k=kOL(ibIhTs9(|0jCiq;&VZ#hs-N0M(&i+=`FaH1 z*rw^joKF?|8q$s|j#8)gF6+BPnU5t!c!n?hg$j<=3vtfaOp*g=D4yDV{q?IDw7)N8 zpZ-mL9x+PGc~b?$;j-*jV|J--^ytq@HpqB%Bwhr=WgJk%=W_@Ua9~m-#9s2<6vj)` z(5u#^gV#sTKuT0H*Du8+8KBP(Qp(spFwBfTObLoNNYk149ZXLK_$13|5p{w%TneZj7Tur` zYO2={ldZ3r2i}|O96!EKRXTe0sMFS8M0#uzUVT|X@QUc3dGISM6Cu22CttDXi;pY?Em(O;*wQ*Bn6EvP`KGR zSO)QWAPkB7Yjm%ddL~jO!Zpi9^6Fq6wrsbf^#nW*SY})F=4u%wdAo&pr&Wb6BFyum z5E%n6hti1MA*gB6I-L<30p8iP;;K2Ay`Kyf3)m&&yoZ-EkfCHlY0tvbD7xNs=O8KDe(_~wEJ#^T}pONAGP4dcWGuQEkHCMNfmEg{F8QQwYUF%3_xs{4A zj-RrJ3iD^TPA1pfj;e1(q)wTD0#=>z`}Ii-jj5 z>*l9YuOW08TyDQ&~eTXa}i>LA0kfuwNqyJVAZL zA%8k>?LQu=SX*e>e6wc9dnbsR-xZ0T9#eISRnG%83$1JW)H%y|SbpGqu(e+XLDirG zVv7}vbW*yKz)B&E+WvzCvIUGB&ux$IT-Lj}g33Q*xH#7L-U<7HB}o0LNz=zLu3<-^ z?g-i*%rv`U8``RID3^ny-VFn&3cd7goo&Zf6pFf@5#`O`vP>bbfPmSSkAR7p96mzQ zeYZRJIi&g%@POmfCwQ2e%wwR*V+y0bCDL@V+W_S35;5?9LDO#UEKt8LGDRV0;-{<- zm-iK!D~+`d3QrDtyR#^E4KEQwzr!hO5g`EkINIq8}XiM4&%@(rLKPmxk*bADDOYgqOL&x^fV!14+auEgxn~+y8ze8 zuTZ=y6RX>>xY$fu+O;Tc025KxbH3vKM;ReFsPBsC0Cnyj4JEoE{n$H3hV2@$1>-fX zaYuaF)CPQTw&%IE#52$ypiXq+0Q2@BsKf(~0Mt4w8eCXP-oXm=J<|ttxqM2Q{n0n$ zVo-S@mhG_i99nfTPXA zmWyReIr#zb-NkYOO@H_3Vd_{sT$SuGzV9}4(^ILF$pWV?R?fyh?K-ofa zk>aUfFKer)v2}s$!Q>TiA~Pee-^5WLDexi$E?sNIktg2VWsW z{^eKu8tf$Fcb{-)d7iTW^H34;MYFXT+72NgylfTw5AE`T#Jf7f*#c4K%OLr0)a7ri z1+>Pg)}leY!rAtk*i4Q?wg0uHzR`1Q=__;X(81=2O@@?&8s%{1FG}r-Hg+s{=e@~o z27XTnAt7bWV+$UhgX5sKx|3iJ*UHRPZ8}0=$neBuC*+}8+{vGH*Uu6f`o14G($2=5d;gT^t<@Sh*XV2JW989&@W#`VM zpDxq9S$#YDggf&;;duBvtsBov>0ZEs?eHeO$sGnE!m(8^03+>{mLd2Cv}=ZU{Hq` z)=>MNF>&m`2vjWDVkKP4La5yv9aMs>T4pyWMuwY5b+9++AeGZ0%$Q7%ZobQ*1|C~f zHxew*PDWn|b`>&F<&TA0c-XzKk_P8JQrQ&ES`S=P>@@>&gzbi}1#kAGHT>)HwX7E- z5#}*%8(XNdHxO2CchKH!shF?*css{`v)LeDsYyFE;nIpS zpq_LbjQ-fR5Al`_dm4${?LO@#pSak|YEshmKYb4?0E5IJ>i_nVj~{);4a!dO|Pk!vf)4*q|eFEe##2LV`Bh3>?B|`ar>vDrq^(ig7e^gifv|!kI=*&5|u1 zyjgrQwEUGdsYw)&<56Bs^Be`^BKEU%j-*{5zM#?iiOhRk0%@M(;=fGD!voZ$s8M1pVp|bR&2(0LH6KEeVSsUjAu#(-^A& zH@Vbd*|d2`-wUcxUbN+O^zCUX;*P(Ati!i?8V5eh`5Gp0&c;6{rFu-JK)@qXJ7#jr zfq-r)8*65tGt%UQS$Mvlc0(#eLIic+8at2Hj%gFgPUN^|l&=ybvI$_SZ3HeYhpdS1 zlE-AGugVMgO|C12FMOP^_dr-LTU~X=w=eQAfyF6Z9uYZX-HBBv`K|8cd6=gDM)ej1 z6556}?ZLnYa0fvs@iIdF-ShB+Xn4URqf4ErhWM>uH!A?U+ak?7xOOMUi$5zw42DXL)?vUw z*mGwXGG7sBwq?pntWpLC0nE^bW=~RGkv|@q;lG!wtq-|9Q9=wtVYXLz_kKo9c2^*EQ$_n!scbmNqx8Rp$LdU6&|Y?3@N}CH`{bZ8U4+ZSLHZ1LBCpY_4?FiMYNah4fVst_xC7AaC`+0g!Ca6y$By&K7v+h*S# z<$ZWNat?GwJzkLP=(mhThC;G|T3lKgmWP=-;zuCZ&EJxa>KU{ zn|%Pq)#=}{d34~sg_PXMj#z|LQ_TLKS$h@-jg;YeABV!Z2MFZd-;3m!n(bUV(i=`$ z>M+IiA^=%Rk2T}rsSfKbYvZGh*`BZ9@9>+u)cn^07WgA?2#SQb!s_YcBaQ#qW9xDH@u@K1lRZSzBQWkPj=D#kv zSq^Nzq$RRG^$r5$7V<(>Gl)F(`~x6kL>Sh~3HW4!5k+hX3VI#lL z0D2J-xIZ(N;WZbtG9S{~s%5Z;RzylAl~PEBv=-S?TL^fh5lQz_eTL!MUKNy49y|rP z=$8?L^Stabb*jjfJ{=iRMt=IFx`V6^SHae{2DhnyGVtRG23waJ`OMuEc8$IRrEMEsOqA;r_GERaUJy zZf~Dy{wN$kwm|eLzmmNiC!qk|i44_E`OFB{9va~R&pisRt2k|8qV^`Z*GAzi>fl|W zcsWMkgfkcWMu9~}YY$B$Wur6@%O(1c6V9nh-1S+B_YR>-wNTg*k1nvfuI(+J1(jTu-;Cl zld5zHOfHEu*r0;F#YzJoqS{@s?jJwfOZ3BZeY!iUzDfjI9Ww17OVJ!uM4I`DohK{= z+%dPi)sLJP31e;bcZ;pQ~y~ z`cx=pRN>7avl^u9#Neo+E8DiEn95e)m~JCmZ!Qbn)HNORUU<=`?y!rg%H<+X=K54YlL&HtNIeR9$1otir#tGvLIW(B z^`598x})$PF(FL__9@F`b&}~vxVDQaZ(arU^ZcO@rdf-gM*mHkNFuYOCoO$f_C1K&q51)-k!uK zL<%Wf_GA{$##f%G7}9|7YsEMs*S2%PL8BbfNzP@n1kVJ+0zjf*_ZX*;KmeCX{9b5wUnQ+W$y9y>cYYZdNDq%IRFB_G+pC!6R zj)T&(3TZ5Yf{(C7G?royZs|9N&?9}e9cYc~9@)sePMa9$beIB!=?oOOkHq6$Vw46q z%7HN$-q!SPE(FVpku<=+IQ`~%nMR{CM}hz4;Q)V*K@WJLxH+Pmonn1zU(KjQ`v?+Ibq#n!WT)!J9g=$=wB z>d4=f>I&may9@e+w9_)%=K1{>WEJ4cMIQF>S9b`9rvj^`Zh5g%J|S1vDS=9UoP<;y z8blnoi0BPVBA`hxISZj(v!66{0+YG4@jm^dReG7DJY!~XnY`qL%?8JnPCz;>QD|JBN4bU6Y8P~l5>Dxk_37G?tQzeK`Xm$nD-7`MkiCAzUJVCrp zLBMtI$kwj#f6H<&nE6|FIc735+Ae(S`tFKR2Le$W1h&rd<#W}cgzC$(5|U2 zLotou-RT;^F6YKtFrjbp8L1xOL=K+`eKvLE$L<+ofNTv`o&`+C>3#wj2NqyY(fln+wAmdn zCnrX~JwGQeuyyNKI^LA1y+0sh`_>$S0TYvzHNI-E0<%;&F+0@Upe9|G0>gl%{s=~t zH1mK2+MvZ*fIDGDgYx>O%rQ`qr?9kt;FiLP4n%06~=XuH&D7NAZBW zutKZwq$DRZog9L;lm^;E^o@tT*@R#C($bU)dZ>ip>H#Id3GYhDJZm_D#1hQv^SY*PEnT?`kxOEAtDy<^ zqD&hhuEEF1B3zwdyw_V(ch7rLMvUy#Xw0?k=)UG@XL$fii_jAfQnIII5uHDswhIYQ zkMyyZfwk_hcs+)Sq3Gvd29l~T<1`g%TQZ6fL=`kyrW)Ds_|_+&0l9V~bdDxq6CfZp zwZQr-xlZeHTMVa*IOHKTHo=YUej7bIuP*^7i172`erj{(?{U0EnWm_EPL_odz!{|* z)wJLXIX3zT6fR{ZQ6`&ORIx|#-9K9HTp_V9UexySGXCzPpn#Na*}11G)&)Nf6M#^- zb~WKHV-bTAJZH~F5vT7aTia0(?-w}WGoLs|R|cFT(z!4O2%?5t@4^cGwP~I* z{+++yg*D8t34I_ez}o)a$DJE(wXQw(R^e`v*$U*rAyg0}&8|;v5VM z5Uw1J;mDFnvs#z@yjfzLnUT#*J*n}}d11UvNP_u=S@~~pM<;KIV*JPFF(H#nqW$7c z#6#Z`bSkK(J;(oYG{VjFfqvaOZ#mwIQ5vQ){ z<{J6C)f=#S5In_YW3^V4jhTa^jvMCdbMRw6F^lpc(*uY^|z52+H`3S|L)wy7T4O zfwOdRjmuS4d{0-M&@Xn%w%;bCSh7Fmi(u#>sF0K8ViW>zQUqfnDe%T6J`vXH}{BDd8f(h~{c2zjQ9whsALcKuVmkXVZa^ z1B1obUC3X3z48>xS_D}VV}gKy`;mGBKiHze5Ka6?gMCb~j>Dc)=Q$<~*uu`|ois{16l>1?bN>u8_?y&8oL2JF zd43P-a>0O&GumI5lGz_xW6C4Q(@7TpOad)FDNr%4g*y9V?snaVZ(^hb0-upJN9^uf z8__FULQKZ-G{k#0IY~eegk>H?b2Zq8hl+>VvE5OzVS{~3Pi#_>>t(ci+s@`Gjt;Xu zh${>h(?Zdqy(e_I*#ERiI5>QhBln%s^O)4IbduN*HT3-A1~i>hJ_+L>L>rWM*_Y%b z3CAO({WTu3Ej`~A&hiLBwQm0e&}8Nphn)Kj_Nu&$hUmm=aH%nrq26FQv*w(r$@qhE z8RdC?O@-ume;Q^469NgJcyN|&{%zPi*f`zs|2s{VFX(!Di4=&dHKS5G>q!(8Sqk12 zzqt9KYK=*201>q>OlwtBb!mXe;}_B25E|ly&<4NjKsr|4;+M-`IG4uJ>^F|8D`v0Yo7~ zM>~C!CA%aRnTV$Dbv#>iB(_m2$BEleY0@!U9Wl>C%~qUV&mGKu^&WkpP_e@sJeSe| zyU}?cVw-$zr8>7m=2C(#eH*R=dV**-Qmcd@XtK}`1hbS(Z$AYKtFO36NQwN9;s4EWrXoc-_hew+Xf6?y_4fX3%fFF->TA48-2 z&lYXD!>$%_qFj)4ap=ovQO4WDCV&c$wL}s+v)so>@KkApXU}L7Y}zJ$?+ovhIAEOH z%ey{GIFeiFBvv50WF+gl|L_vtW^oHn5L~H#M$FmM+(fuqj6&lX*=GBbch?y-CP8@5 zBT}dcuvB-n8`u>QQ_9pFU$xRA40=qj9D{yzGm-S*u+kg!qfd;sYMFc~!4{2~Bemna zr;`rpww`*$duY@q*M*dZMj?b_e6+a?MoJO<%n>masfc}zVU8IBO6oE^nolmy>10ie zVXL0hN-!ia*c39Oo!`J64Ezlwkh1i|lc$heZ}(cYdI6-QS{lo9hl!;?j32s1TQHO{ z(TO^O>rqdV4(jtcvyk=2tU>o&FA6|LtV1+A>Waw}_F1>ns_6TSUtdWxz#P-e2wzL- z3N`$(5_(s~Gr|rDEz>gnc~zL7D6_8pGz=b7*2uf+|GCOZcME(GrMA_-MntZQT{N!$ z=BQgmCC;%D1-lqDmDS&o&;ddZ3G(MELf8Ik!d}v}w#w2c*rjo~6j(D%@a<&*;CbNa zM=&CCY@0|&Ecg?Oe>@7LK~4=j=7?;2#}z-i+nvFE`J!!XV$#v9`Qc1|&mX|a?5PWp zx|(yuH3lKITj{H9$9?Io_&HAeWrL5m^DyvlUTu1YI?aG^5UlaCZ73x zWf&C;LX;W%O{cI!t-vrGU1AGBV4*YO8ii`g#(6Fl`9l{`XC!lXsov`)RB|gxvek9+oQ{~O~KIQ3K_S? zS>r4qkv;c@h_gJahrL?dUp~L8D`G4gHHt=GErPqa3ybd3cHgF|f2G%u-vGJIJ_Lqw904`Xqx3+LXE zSEX=uCQBeoK&?V})t_TAdmTOM_}pQ_E+Lnl8bA4;w%_>J1~yZQKvSYrQjsv8CSBJ# z)FTiZRL6ID!dt+(71|_D9b6d9X?M=d1KE|U=dPO=aj6gf_(FB)?)#32<8e}(KYkVaMO53z+f)h$v0DNc@YR;k56}o zD?>(BjUe{1%xJHQ#bF%h%TmN=3XGGR-+`gFWly<&XO~a!qfZO9%g5Xi;;tp3-dXt7 zE%d&= z_ZmJ81oc&0Kj7~w={BJ7bW5FqQ#bQDm32Qb>?;~97{LBI(mLV z%n$<;vc#$In1%h3MOvMAd@2Ma#-ReWUG5^Md-i+i;*djk|N2T5@ptm_`*(~WZXZ^B z1xvvXH$ptCX36*H3W>U+F_+w;Ik*!BS|g8P`hX&YAn+;6PfVc-{7I}@iZP0WwOFTx zm^rp0hRg5a4?XP>c5cI<5-pIlO5U;9-q0eA=!bth;fXV4OKzxTixkCAgCzBI8owUk zN8ujL#I)$7(Li1a{R?rrmzkdriXh`Kk@~J_4@hrMv0t-=BzA}7YsfLZXRlg&?Wrfn z^@TDW2X-N+evBH03gmD&$sMpvJze!1anAh;>J0?)cxCy$0`|+CvMyZXaiPW@4AP zfWv)>iy+wUTh<+q#`lY8HF0_-Ea4m1Ms)qh2lMTzpN~T%O4^c1zoFd9Wl1A~cWOGV z0k@|%P`)>mlI9?qIGZ=)X7gP%J3mz7=|;m=H!QdVR`)4hJJCC)nlQXJ&7XRw++ z1k4pfI^p-b5-l}B7OXc-^mR3Vi}~Bnn~vle-WUDA_?ZK|$OkpIs<3ON&sG@^43FLn z6qnFe54j5Oh_(&&>oW}B2LNAe5xJj=S&-gwx~2@YF&{40eWL}PPaJ~DvD?)Z6FV16 zWP2DATJn4G2(hzJ<%igh!Cx22!tc;R<#Rsd0(|SSRQ~cEUkqGRKiDw`J3cLYidaWR zdGOr=b~Zi(oQ$N{C_Z3Pry2Kn3==j7Hykr$T}p#?`9!QiZ)uKeWlHb&P^eoW24;4XO&i?Z!8&EbS-F02Fm*nl0Gs{EA}RKAQSCt5!3k(@wf^6H%Ae1 zGhESzf2=05UpHTMMgUmaEM7y6k09?%L=zQ?eIc;oP~V54d*|Ho zs7Bf_S!jJi#eI^V0ndzCY7~qSnh7W>XnPOeZo=AbrrQc0?3aHrmZOfm%qnDkm7 zhcVv;C>vV5N%9pqxx_#uzwE?%=S1peO5dd^f5hRAF)fn#VjYw;Nc?&WQbk|wPbU$vd%NE>3;`UKml4|O`izpCE9QM`Y9c+~ z_%=iHKI%Pv0OisbKIrNHt>c^aq&S&z)dqbaurS+UtJleMl?OI7H!G=buGhppA*OnZ({tvZ z|EXt5Nqs9jmCV?OwP)8~bs&?SHhujTod@DfIDTl`dc*}z&*S(9FNydeJ0o=Eh9<^< z_Na*)kc!f5xNiOqbcZUHps5DuasQ1FaoyCWo%HWUL^YoH+gC4%NO5k-P(AvWr-Cob z=Y{ZhaJotE4lyQ+>xarL1p~T${w|_7FePJ3eD*Z|uzP#M{?UeFU7V$ID}$mAL5Fhb zcM{9YB?z;<O{t(K!2 z^K@x^Fh&#X@I{6^m@yaBP&K%8NRhGgjr=!90;l{UCOB5Hzvn z{MUtUG%T6tHG#v@l>if_(AK{+C&<4ugjt zrfQj^u<(rQTDnWv3k!-ZEST8PEMA2TIJ7gqN9v!xl}~~sq48j3jF;HqQ2S-)8&Zn_ zi`EM58Q(zL3jjLr*TD|OIpHGjtuK?3ZnY60a=}KXcZ7}7;bkhdL(=z8C zWySQYDg79cRGw|fXn^V+#-b8AVnu7zzfCX9<~PLMN3x{f(YBa`xdLVlIA|6@WMvVW zM3z=32%+@YkR*=ki?B0~2-pL|!6qEQjA@2)zD=agjSy0$0J4Rs z9T9nr9UmPG$H(3=&H{=wT8F5>wtO58#_z)HFk9qPbhU%`HO`b2DG9hOp1?V*=~ zj*Xpp?@00b_Wq`v2xcu=SANa3@8Y^{gk;Afzg>*t{mI6fTUC9ybgH@ykB|g1v4QfJ zmS$Ub-*<)7h53p2jtNKy?*cigibL znCf1jwPWzme05F7+a_~Wy~ntXwBVn8J=kWLDp60zTfJ2{M)?Trw#JIynSOjvhB$Aq z@=0&`39)4M3LUJOMQN?cSVla%UWyiK=k=sLlTg?S3wU2vz4lydpJQHwn`I%u{c$I+ z>I?q-ugi(3p*#KZ#naiA1Dg*a<#HV$bv9M)b$Bay4o5fJqjO^^qm^5K<$(o+-L zd1XQq2{7DpB>;=lBtUpRK7^OT2W11ZG}bBdepyn>f53sKgsK|iq><67fSS;(2{V`A z{rg=3XxRAWD(_JL%tpbdSMYAUNZYvdRdN6(9&pp4#8r;i{^RzAyIryy z@a&9BL4lo%x-O#JT;HE``)(%k^^4n&i=caD8m9E|${O(8 z`N-^+2t8Yo_r_VZxFSLS*?*a&FtzA`)Eg@LV|c!&%>ggP{$-v-rJ6L^s82q^YLP2$ zl719=Yc;O+iD7DP37>zuNN|+>McQ}bQ7}t_$EajZD^5Mp+}|;cfalNyW9^ehJTo)+ zd)8PKU^dc*xDwD)#9Zq&j8{vL&O=y`2$!(s~+u$iH+GxdG5O zJ9|H2L1*Cb;8rXD85KHOhG-}4EL_eM+U>NVZ&8&Iqzl*#W^d2hw^$S_A1|8|a|s^4 zOs5=bUQ%M@Js7G=KFClmn+B9=*9IVJfNiUy4FDyUgi6b}s~{>0Xtb~+eQLOYM%Jf9 z`%Eo0cps+-1NLUH+`-|$*ZEL5{h1k-)C^6P;+slIlcmLf|0D*)t1T!@3E2(}Wyu@srG zJj?(W9Px(m3X|Vj}@s#Z$Jm6I{O}w{@*_A|U@+^Tf4&$o?-0qaTIDHb1wC{?An?gKl;uGUl?%+I5(I7MH)zQEJj_`oHH* z*TE(XbHdl`j_7j@E-d>blthpkZ!l9hkuCA2))Zqo)@b|CgwqBawddpKe$(Zj^;{%^ z;sxw(Mw(tI(3T2@pS*Um>zov7bbKnRjF_w0NQ5jkl``3s47yxT(b$a~ zRzV=iz8S{ZQ=Q{E+`|M+nK97Ws~34S`eop9WQR_5B)8ZA?W;PYe1XPRco?#PX;Ul| zWh5UbFy|p%+)B|`55$?SsMBR9%ni>de4e5|n~Ay{K~=+UEIDO`H4Re|vN1__H2ZWn z)`X3a)mO%TAYS5kxAyN`OPG=o~wM zDEgr%Da5`L=GPw{k4@q!Z;gUPXdzm$yzDiI@t{IX;69wcoy@3D{?n%W_3$}hT>ODY zNU5;wOf)7{IzV_|(g&b=I#!PO z#s|yUzCTvb*^8GMWyg{!=vP7bZh#JBq1^X0N0vrVxTAYpy1)p`_T%2O=;FHBZu#9= z;huRh&en(2V_!K~vSQm=y-WaWJijB=L<)w&YdGwop%{TlMRtvP{a}ebHdK&++Jq_ozAccC1lA$E&~_lYT+H|g`V9<9i=No)K?f}wcS9%{GWnDPLj|D``;ux- zETS;vLpU7CMlUb9`Nqe-sAd)hCk!v;I_f}WfkE@Z z$2skQmnxW`DnY%$d|VlB8A8HM%7!OZCQqkfnl^mmZs4WVzEYs)eDm=~6D?V$zX?dF z%ag4>KzmUWEvnmRQoDPnoR?v$#jdvu22505k!G@c|D8s%{Z8_E`GSj2uvupu(eBAR zrIh2#>rkOK1Yr2E3-qV4fk|IpM6!(qnq4X^_DL%& zdu}M14@xdPng2U^+f+}#zX8#U5X*VMl_9D~AW&Rg{4ucv31*Dt;uqoW*RRUa-2(gt zxjGV$PcL%GwJdo1HvEaElKZWK*oom{*UnjI&NcK7W9!TMCZQ9zWxz<1A;QIr7E&_$ zb5E9^MMLPqzw^Cl7434}t$ZMhyjrF*$NghwA{QeLQp7t9a4JzD+mN%U80V0|% zJWbJu*TzMR`RBeMvd1d877iy8t$TFtW+Y?KN`?Uvk*3Q89U)8TDFC>5A2k6@$3zS{ z&AFeoHEzGD-2pRI5p}e%3|&LN3uAsF~iVrE2940k0KI^fC`dgR9vaA1-JvQ z=Z;5@1EX>{m8poeWQ(OMp2L!_T?2w2z(>qXe_L97HWbrD4Fg~j9SBOQ@ACq=Ay9BB zd4S>C-l6Izu+(Aa>nNGJ!^W)kGvncCATFHWEdv|cS`=Wwq^pp+`C8s!!M4SyV37Vb zk$;nJTSXs9YfGJpHnU!q$>>R zlnkh+8<+=wUBL&c-Yz0DD}7yE-HdsyN0n)KkTduZaaO021@}w0t7V!4R8Af}NFICM z&iDz2tmS%1`&u7;iH@(d?&*1vN+US+GpaWnM|uchaEO-Un9cI8SL=vAMBu$`{kLn0 zCy2F67Rq!-Zsn?r9Y=Q!bBk$9Uf|+Mw_>}{+G&S6(}BgkIT}GJ;J4g83orzkQ0W%0kxv&JJ4DS&c?tY9}O&7L50tp3t&O=Oq2i!69ih zrJJv(29PVv4BPz%J3B_VBQQYtP=KFA#2D)$>u$=zyG*;48I!lJg&U4TrG`w(7+tBe zQw=fx7Ep~-YOtGq-$|Wg!VuLJ_@#=p_&gafl%SObMY!p@k5N2|a|oA`p5p zgcj<5@9tb_B+CSNzwbZ)IX`obcKz(V&)n%dWoN9=suRs!7F^h7D_Uh?cyOs>iNBp~|SW53g75o3VM~{i@Y$ezw8aZ!EQ~ z?{u?ix!Ma09`11INTr3<72f_cEzN8bu2(l+QcX_QSLyW4`0F!I@0n&V)oaz+g8brdNR$3(maUklZxo%9iM2zL$4Y>o(@6_6YW|ifjc-4@YrNKTNrNj3^zB=<-MDVwf68nuJ!ntrgi(g^O`aZ&Jbz$L z`ANMa{%q>^u*=XLk52@g+jppj*;=>Mhr51U_UEb9A0{nJu5|XFzD0sAbcCQizY-fi(7?c&3{QSU?PRf%rY7f6(c>D_O#`ZV&HTh!ZqZyTV&TJQPtIsviP3H`RI&&QQ2R(Ic{n;i_NH`=|sRa>^OM0Vv3 z>ftql{`#w{U%`Cdw=HG+AN#&}+NRYvJ8cRIKhfbvblX!eTIMR0bHTIGpZvFgD3Ga*b6keaDzEEX!VjZ;K_1j~}o3yKR<^2UCCwf0D-n7jv^Wo1@ z>aPCJ`UdTnEFREo?u&`{^9Hou_tnq~7Y=*RD`4Du;OO8}Rc`4w{CRQM(A$4k@@;hS z^9Wn|{>W0RXVhvov&h!%-8-G?dbCU5Qo+*>Z|ymx_wMsSXP#W?)OO)7S07DDoVDe| zY2~Au`>*z$Ipd>O-EM8azwU?2uSTx;G5k`YMdPY$9TOJQYQ@d?BICMU?~*5?=DyJt zYwXWx|MAe_55t!|9+>MI%kCaAFD#F55Mt*yD za%|0YStATnigd4BZ_A;qK3yuLHhGbjvC{XeY0G-%`|OgPU5T61=jWj6Y1#3U*LS#4 z_PZHXn(i)Hi35W<9`jWSfEM0EnQBRtABgemwj6`TzA9oLir;lN@w(XT%^*#_O;6Yk@n~3 znI(sY^t!vW$>*tL9^Gqk`lJXeb$9c_GrG7h_fFDu(H*%%L0>`XO{Z3uLY8vv#`JNMx^th`ZxT00(=YLOl_D|uE3M+ruyK8>aF1N~8KOLGr z_dnBr{^^SHh(b~8v%bs!=z4ZT+q+*Wj>WAm_wus?U*-GA*0OwH`prXAI+t&Jua5uI zQ>7X`Z`gQe%&Ur5|4BW6wjR6d`@xv&_Ek?m-SWk>5>uY{|84t&v)-B;w@&O@@lU-b z9e>z8bko-Q|4h8zp;XZGlrN^tZ5mYNxapUmIfVw-nzZ+`EzgqgPbt%`b)6Q^qkri! zE@;V$v+50vj?Vbjs`_jw{4eri7Qb(2u2^s;^i<>GpX8Zrw$I8l?OuG-mECRk&X4F- zyV%l?)dEiUd{GB$mlss5ewrAN#k7;rSC&?n(5H^VH(#6&AKYzQaQgyh#tqARqs*XDEB9{M+;;W- zl3ks#6BZ(_WJmt#as5SR4KTePu_+nt`9BpxZv0gTa0JAoee2sQayY!^^d|g z&n0->DDB-xxqWHymyOGuh#KSD_u9s03%A!iSkAxnK5NM>rw8s}&u85~HS-%desFu0 z=OcVhZ`<)j+WIbcIzInO8GKH)>S4g9%3B6?9d&p%Y(*aOO;&AH{r*?RbvW|zf97;5 z+up9Np!5E&fMI%Sqa|OaXEwRnc=ffm1%G(b=u|~};k<`TQ*RVpc6eU<75(AkyBp2A zR~)^d^sw507y0d2={qAoyIt_-rE9NwWi0;MI(WyNzU8AXHh&zd{kG*%%Tar!#VM)E zv&WY{E_&bVmvP465!-%Bxb)MhVxQhv*f_R!^C6KFuJ7w(=@waU(>u zsE#e%d7;~u{M(w3EYZE!#WHiIEV}n>`@XL)`CaV)v~S~U{ff<**5c=1{L2R4JJEN> z`7z1gwEwM+@BPCwdOmJ3rgf!dA@kQpZW=%6^ExjF6)RNL7L@s-_tjqTuVD^ed9dSZ zn~^tPoF1KBp=|pDm#%jDyH`r)=G1}z=nkFxYia!UML~I%Ur!(V`}eBP?$)UMdmZ1p z?b?5Tz4sTD$6UP{I=0!4gVi^cYxQ-p6MtpZtg0`eyONO=+NIIMgVcSa zUKUGH@5wCRbw~en?a1?;!*6B|D|_(Q-g9;@I&r7`+O=K2so$*Tk*>8%br}2d(#x@% zp#A7pAzad-?v@+YS)xk({3l+jhT7)kHuYQ)*YpIy5>&Fa=Th@yzqIm zKE+PtJCQNG^1yGO9VxMC)rM&WR@UgZ{#o3G^YP!Nmp`ufc;l@pL+vv@xZLK;ZZY}p z{m~=h{`&UkJ`S!@`Qr6y3pzF$+dQe%$l~QQzE`iP-`>9Pi@q^Y2TUPNpIyy=U_*i7 zPoJ(Gp!&Q2`o!&bZgx5|@SJ(G*RHVL2_4VOnxHA5-#6{?x*0z3KVp8XzwP^C;rcyu zM?GKNzUuFuHT{j`2R{i{=ZkUU?K*%)ZeclhWf^*w#xS!?$$1S)^~(@liJq z6-%v=-dMYD?)AgtTj=&~`LLj2$B<4@CxY+4nAPsmljxlz`_Eof{7JD-#wgkH`7{3f zePcfM{Bxymo=N#xzaXE!`?u#|zyC8TZuc<8ww?@pHY>}Q?OWWuN5WKZwz>F=48MZ; zneB%zzx8OHmwj1f$ZrkXvK;PJ?(XHQSI=uPg-qFd`GOx@O<~0oA4g*~Nuro^Q28J@?w^L)QisnYyM)(VOGvT(%}%J2LR(*A;%9 z7&>V5zNzar4=Q@V=i#z%{R&mw=Vs5it5WF^3zYvE8aGCLqhd&*zOjWSE6Y^*${yO! z)^Tl2w>ygYgQ_L@v%>ur_pa5|m$l1YdcAJlyzIuXmREcRF*ZV1W5D&{jJ538s;d}w zmq5OH^>X{V->INzt2iL(Lj}iUyQpQj!hKFgSXk zZkU6Ts5cBYJ5b7CGr%OB-tnZm^HI|#>T1=bps1^;yR~W&2{t-}X1-u!HG%cYE>XLgPW4nJT!VYs^D*+JS;G$T@wAKE|o9S3{PB zVU9}AO%9I?DT#V#rkY~3Nm`>rC?%BOt(;K8gP|$Cq2I{9@g`Y@K3M zn-daEYLhnEkff_AgYY`R(ZkF-waIKu)W@rbBqk-Pqjl=RCS9yrYf{VgB35hGvdX50 zm17&KE1LpXNG+2wrdC{{E-6-%2%d!`FsVX9J&R2=C#L9m)odu#!8jdMKVvdfZIW7Rj31n=)0^c$ zxGV8IP(vV0i6%27$1rtF0;GZ?Fc@@Gj8SWjNnnY*P2pH=GH7FTtb)U;2Eq$<00UXA zO1v((DHK(s&dj4Om!&t3JE@yADSBPCD&`>e$w$xtVzXWbem?N43qN#tSHkajZxxCa zT7{RQU>RjalI_J*fhwl7shD@9 z4^w9PFohlN5xyYzWlB5TBmJ1S#h&smv~-WY!W&g}tPbsULXzL_YEMVo$x9Jxry@4pVunYpWEYwN)&;wo1vuRoVYS`TZk)@5t{x`TdOo@&BMwQ~}pOWxHXL z{+phqwX8|^$Ot)m=xz?^ED?3cOE&_bKo`1>UE?`xJPe z0`F7ceG0r!f%hr!J_X(^1qxPB_Y2*sF!&h);pf-8P=rRKF`2b712r)T12yr3wZ>T1 zbx@#Hejckc8V$@E5jzZ~w@l{2(VFN)Jv?L> z=r!>%u`uC`4?~5AIy3lZ#HaP0PfgCJ5yDe2t4GbYk`0&`i!ltt;Nr7Lw;13=I6lXi zX`@q&lHn)-aR!*xGsmGU0ijW+!@mviH_XJroH?SQh$R03Nlu|*Fm2?V3u9H=Yg4tF z6k|Ljg*gVMRWGkbvD2h!wxESF>Jh-IBlw7b{{^~sbSyyO4GBNxWW1uoFmk* zP5GD)P2OwGFi*#t}B=lrc6QmvVx5V6-y!J#nK9ao~-anA?Z&6 zQCdk5*-GK1G+eS_UX0nwf+nAd)WB47QZ$qwwp$5>1?FNM5B8$ZFn`9Z<n3^%b1u7$*W;URZL~j8cjO(A5b(VN|UVYvR4dSuhPTRDMbI8N}7z;umwI4z=~kR zULTB@v>Nu%D}f#K!K94WvpL?W;6dClHbzDB%Rv5STU>0Tf9kRzDvvvkqRxece6fT)j%$sG+ zf_Wk@9-h?{lYlA)&R*d8C?u2Fywmh~v+N$@8T$Aa9t3FT>U zg}BAWvgayT{$OiBlDUhhrvkjnNSp)OJ-n>Me0e@rI1z%WpV3&O53dyd6R@x4Ux<|V11%?t;UI@m< z`9ad`M|svEluKpeb3dL3D^Lm*9|AEO=8U~zj@>xSU}jmQaM}-+9i&IU`{6ig8rGFt#o)Q<{f@o>b>21#kml&X#6I00i}65eRCU zbj^Y*6kL`bpb2At2S`;XjBN-=U>SKGh4ff}lwhXP#lK5+WhD zA-nSMqQ4ZaNxHmk2$Ks^7`v87ZZ;eb#sVA5*P}dG%AbRgY)esyu4PsNTStOgIgjd3yI4L)qZ z{>&Gvi_^kVCcBm|I?+(4ZYZ0TUl$V#EgjDkHa|a*_LcE994KK`Wh%22Hh-Hc%`2;B zmeN|vkm+sp4z#Llsz95s)h{s9SDjhI?qlnom98{o7O)LXQ`)?&Q?D?#p+OB(LTNK&KOn+NsmVb5;yUNqO$wg6_%hh zmA$mBkX>o_&a9YLA=59@D{FvN6&M<5Q&_yLUZGYmtJ12>^2+kEdt1G-mD$SBY^4Qc zC{M$6q*M7Ai{){|TVQ@yTn2EQmxBFNU{n;!p>1R#aKW`Hbg3Z!K)@*f0Dh4u1c$gY zTttj~25kyDc&|%*!o*igQYT-;$X9dz0nR5(d<#Yn9AdODV&tdgmBj2e=MyG=nk;tk zMU4CiNH=u8uug*UCro^cBo*un82L8N59WNr#LpD;G5jJ%z5&9Gt~KWqCcc>7$QQ9> zpY!!(pJU=jNWMG6FJj~~;Gvts`GkodB}tup5hI`0kv4EXVd96n@kNY$E4P1^^9d7Q zwAUH!3H~9U*0)}AK4IdE_K+`P2QIn)3;x8rI*?0F(-R0V5yQk0rN^^9d7Q&6o2KqkR!0 zAG)QI+sXNaiBHRe#1}F011rn?i=0oG`2QCFh$=Ea0Mb#azZ?@kOBOrQPsEaaSSv^O z0p|yDOnjTSEJuv-7cug)YRK|VoKM)n=gXrGzJQT$4Uzf7IiE1`)9?>)#1}F0Lqlcx za?U4A{K#UmocJO}KCSP5&-sKMeEb8PgD+qy{%vIWF^WIO#1G`{Bk@Iye0z79{}<;I zCcZ%yJM4=X`H?+j1qIXt%zp=l$5Qzh(z`RrLj{a{OD~yUmh%aNNa6=z0@$HdR{b+s>IR#zzMG57cuhF^2!ZF1m_bb zeuP{5A!6j)^UDg+oKKkeQEq$@BR`^`tT2)D2@_vzFFM0R5hI@!mH8Q*Pnh^txBM3| z@~vfLeir8wCVn9P0S<3yU&P2yD=YJFaXw+x$NWoktA8R!enbVC?*sK(>c4PId<*!2 z4l&xdAOMFL`8KX!mh%at9PMYp4;^CUix~OVin9H>oKKkeHd*Z8ix~Nlm1TvloKKke z5qx}!810K#vd_OGGn0LeiEr`2&^yB~V&n(bmF-XCe8R*R`_pJg-i%wI)(j)|Y; zmVY8fzP+u?-^uxeiEo8+feta+7cue;pUV7moKKkeX|*M~gD+w!{JcYOlfut2@$GKu zCt~DhFOco~Lq8GAA7SE){ZT3WyuXTa?BL@c;P8gwHwYN{>gO_l2Imt-HLO3G-f#hj82KVbeioAzzTter z#E+;Z(H(pdBR?=m=I`fx!o<&VvoB)g+k<6=E1XZ5_y%FThv647@+0fZeBa`7{u3s? zUCv%d_(hET&_*)9BIgq(zO|}r{6&m>TeQq?%K3yH{14su0+zzRMCKbfKaykOXS=ok zB1V41N|`^A^9d8*;ue1qOW{wK`O7)q#xe1u+}aNjBVU~%^S5(8VdC56=sVM2z{qE- zW&Ux_Cro^cTl*toV?}A%f4@Gm|CKnd#&Ii-+j9IV#|a#N z#<7*-i5#bK{4HX5H_-R`zi=F-mF@k-v4P_kfYq3h+?9uULp1@oH+REvZg{#IUh9TW zxna!zSiEreH^^fNz >_C?$UFs^SLa$Dc9Hk9-8ILNVl5=O7FeDdn$D4!z6@|ni@ z{^evoVd97KFd@eBEn?(naeh0_Cro_N9`Z$ud^_h);(Wryx4GFDG4j(I$?@Mq;pdq6 z7W@Mo-q5~?k*{td^Ph1(VbsU;v*I7%@P>R5BR{jL%x?joR!Hpw$Ec5dF};v4V&vPo z{y5GjOnlLvC;Ns7+5TS6Crtc6`~w``kS}7iZ)q;`z14E~38TJLe((=)c=N=!ekAi- zsbxN4;%B+>MU3{NTFU$hoKN^o`Jt_4{(jCUOnmWuhT#`6+PAiq`92kR_&FxN75@N- zH{^>L`D)nTg|2-CnNJw?G5rkq2ROVTU&NCA4l;j41#X{X)PEB`?MvFu`GkotmN&F7 zVzeL1_cfj1e8R*R!|N&hX`SWpm#Zj;pD^()5D#>Sk#9i&4l&wScai!1IiE1fG5!|( z103EYzJQUR7Af=7$UeuYhI||R&=KDzA*cPQt}_2R=MyIWzuC8cEc0ttlH*U9`19}& zaAcqGFwj>^68VDi*S!y>fPSo?p8*)(2fw(z4=j9tU=4^ownv1~e@qX)9O(#;h(-JH zpqw8_wB9+BV_JXQ#4)YM9p{+Vt8Q{k>n&cDW&ddYw>-x*A6t)OnqTd}G0m68aZK}< zqd2Dd#CaUk{NP%`eE#ca!hHS(_K`~Q3*_@5k2t3J3BM{_&gUDda7^QWj3=fKjmHx? zrt$S8j%mESf@2zg?&O%plV>@m@nHarE75-%@2NSa@mm9qX*|}QV;Wx#qVq z&ljX`^Oj20LDJ{rlWdM@yb%cFd<+kbAF6OnJNul=Cmd6MI1tul(H`}O zLpY}Xa08C1KdeC<0O=Pc$7dAB)E{2NG4+Qt0ha^)Ox{0MV%vfF&--g1aZLTq;T%){ zZ!5?2KK_Se>fbZ~ztBH=|BmFC`cwFEBg*N0dY5BrpKC*aP)_abXpZT9aFAnqp9FaE z@bms*3y!J3H;rTJe;(kN`cv?wqGXTyM{PN#{?25MssD12dPXY{>?bHavaO`Y5sEp$21?kiesAJ{E1_lFTTogRvX#=3yx|2x+2)d@X+@q z9XPgBl=X356y@~&#xl~cD$5UWOy5`h!7;7(JmHwuU$Cs9f3&_+g=1P@X~8kAm&73k zKhk)5OyYPl$E!Kc;P^Pl7LNZ$jPc{^A^D*mAg1+*8XT(w<@j{qn7&s^B7MG|XXTjI zGvVV~$v;{j%;K2V>+W+*>u;r?UV(XNWn@=L#_&jXwcYSXZunz293^9ie|k4;al>=n z@E30QD>uB(4R3bCJKgX;H#`MGHWhx;;5Qw9GvGH9ezV{=2Yz$mHxGXE;fG5u3*iSY z0=rMM;rF(DHPhtS-|?C+vuW3d@UisU@tq%DzZEaX$K7wm*2QST=#y&rf?C=r@a`VS zpIyH*U-*dot^IKOQ2Z_Vu?cUN+47guVUF+FyiGQl1BRa{as8W(S1L_yZFPuyMHSx>a0`eflJ&A6c{&LaEv0G5kgVzz& zLB2iBv(UK@>~(Uf^gDAAJ(sJ8<4xyLm?JfvM9+beJ(YK_xrIj-IXAR<6z3WnnJtTR zMg{_pd!sytiOX{H*+rbI&s6WkRKhoS{SEfAH{uhFbEu zo^Zl0??Hsbuy^qW4+jmwBRp$~=Xh$8w82iFQ^Z`N5#<}boL!Wp9>#y$cgR_GJq9S( z-b}6nm!Nv60c7SiA}mp_>qqdWA%~784n{MMBH%_-b%h^6;|ZXSQO3Mc1h-)2E56>f!d+M=y#_;g5 zYOZpz^C*oYU83XSd(Ix9tM4AI>0$s z&m0vaSB*D$>wC<0mq0r-=&kL{fAQ35JZxGF3HAAM7Icz;Kb{D=bP^q5^2Cvaj*v1q z3>(fccODCpvkxeAzTEp|&Y~rn5(u8^HRgT}vvLDL2P0th=5q%w0*!|;2%TxI2U~FP zOs-TVOW)VS39;iMIIlu) zih~2qMH$bR6sWwI+KF(?IvjPbjZT6}1Shs@q1w2WK|Ez#pX&Y;^x%MWP7w|02PbQi zQ{d3`oT-kYczjtUy1e)?m10u{Ll8uN;61246ZG1JvML z_Z(^ANfX*T9UOb)VovnQQ<@IZYvZts;@U9fo|>?Ke0)=L2~;m{fhyS#!X2_f{CRD4v5kk@%VQJ zIfSQ@XtYW3DPiGKV=hbw;8Pd>;J;nq+4?*qLg?QVxai1vL@66$(7L^BqzJ;G!<-mH zJwcHVNhl@0CSH8%ESe$kj!bsRP)`}}EFvN9vHur!DOH@gvvKsJDKKv%fc)%%f?c9qVy1kNkKD- zFCM&d3r@~Aq?>|EvoD4^XF|R6uyz2PgI9}*2jRIbl)mGTImFX|d4N7KL|e^e3=NNP z9R0cgqy)X)LJa(W7di*)t=26lRo`_Pn2!vdXLY@mbvd)?w5)fb%AKmWS@`BQkx1)3 zbdJ|s20%LK3I|~C7y)4^`yE!IX~^^c@8TbfD*xv`26*?y{I^|<7kc<%a`Ba3HCjFX zYb$X$@pdhMySG%hB|qQYE9&{bLltv;Zt%{PRP^CpYZ(qxoS!ZHZ+!XSntd+sm2NZ? zYayRa_<#S!k|P8j-z@H0LZ>&(^^itEl3OpuZK{#fT)Ql8O0SB*zR}3swS{%ew~3{nmuB}tD}Vfc$nIehDCGT+-F=?s|K^b0 IwNSJF1Ll$iqW}N^ literal 0 HcmV?d00001 diff --git a/src/main/resources/native/windows/x64/libsecp256k1-0.dll b/src/main/resources/native/windows/x64/libsecp256k1-0.dll new file mode 100755 index 0000000000000000000000000000000000000000..479a343e4fa14b629aafc517c23cc5ecb72ea436 GIT binary patch literal 507193 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

Verifies the given ECDSA signature against the message bytes using the public key bytes.

+ * + *

When using native ECDSA verification, data must be 32 bytes, and no element may be + * larger than 520 bytes.

+ * + * @param data Hash of the data to verify. + * @param pub The public key bytes to use. + */ + public boolean verify(byte[] data, byte[] pub) { + ECDSASigner signer = new ECDSASigner(); + ECPublicKeyParameters params = new ECPublicKeyParameters(CURVE.getCurve().decodePoint(pub), CURVE); + signer.init(false, params); + try { + return signer.verifySignature(data, r, s); + } catch (NullPointerException e) { + // Bouncy Castle contains a bug that can cause NPEs given specially crafted signatures. Those signatures + // are inherently invalid/attack sigs so we just fail them here rather than crash the thread. + log.error("Caught NPE inside bouncy castle", e); + return false; + } + } + + public ByteArrayOutputStream derByteStream() throws IOException { + // Usually 70-72 bytes. + ByteArrayOutputStream bos = new ByteArrayOutputStream(72); + DERSequenceGenerator seq = new DERSequenceGenerator(bos); + seq.addObject(new ASN1Integer(r)); + seq.addObject(new ASN1Integer(s)); + seq.close(); + return bos; + } + + protected boolean hasLowR() { + //A low R signature will have less than 71 bytes when encoded to DER + return toCanonicalised().encodeToDER().length < 71; + } + + @Override + public boolean equals(Object o) { + if(this == o) { + return true; + } + if(o == null || getClass() != o.getClass()) { + return false; + } + ECDSASignature other = (ECDSASignature) o; + return r.equals(other.r) && s.equals(other.s); + } + + @Override + public int hashCode() { + return Objects.hash(r, s); + } + + /** + * Returns a decoded signature. + * + * @param requireCanonicalEncoding if the encoding of the signature must + * be canonical. + * @param requireCanonicalSValue if the S-value must be canonical (below half + * the order of the curve). + * @throws SignatureDecodeException if the signature is unparseable in some way. + * @throws VerificationException if the signature is invalid. + */ + public static TransactionSignature decodeFromBitcoin(byte[] bytes, boolean requireCanonicalEncoding, + boolean requireCanonicalSValue) throws SignatureDecodeException, VerificationException { + // Bitcoin encoding is DER signature + sighash byte. + if (requireCanonicalEncoding && !isEncodingCanonical(bytes)) + throw new VerificationException.NoncanonicalSignature(); + ECDSASignature sig = ECDSASignature.decodeFromDER(bytes); + if (requireCanonicalSValue && !sig.isCanonical()) + throw new VerificationException("S-value is not canonical."); + + // In Bitcoin, any value of the final byte is valid, but not necessarily canonical. See javadocs for + // isEncodingCanonical to learn more about this. So we must store the exact byte found. + return new TransactionSignature(sig.r, sig.s, TransactionSignature.Type.ECDSA, bytes[bytes.length - 1]); + } + + /** + * Returns true if the given signature is has canonical encoding, and will thus be accepted as standard by + * Bitcoin Core. DER and the SIGHASH encoding allow for quite some flexibility in how the same structures + * are encoded, and this can open up novel attacks in which a man in the middle takes a transaction and then + * changes its signature such that the transaction hash is different but it's still valid. This can confuse wallets + * and generally violates people's mental model of how Bitcoin should work, thus, non-canonical signatures are now + * not relayed by default. + */ + public static boolean isEncodingCanonical(byte[] signature) { + // See Bitcoin Core's IsCanonicalSignature, https://bitcointalk.org/index.php?topic=8392.msg127623#msg127623 + // A canonical signature exists of: <30> <02> <02> + // Where R and S are not negative (their first byte has its highest bit not set), and not + // excessively padded (do not start with a 0 byte, unless an otherwise negative number follows, + // in which case a single 0 byte is necessary and even required). + + // Empty signatures, while not strictly DER encoded, are allowed. + if (signature.length == 0) + return true; + + if (signature.length < 9 || signature.length > 73) + return false; + + int hashType = (signature[signature.length-1] & 0xff) & ~SigHash.ANYONECANPAY.value; // mask the byte to prevent sign-extension hurting us + if (hashType < SigHash.ALL.value || hashType > SigHash.SINGLE.value) + return false; + + // "wrong type" "wrong length marker" + if ((signature[0] & 0xff) != 0x30 || (signature[1] & 0xff) != signature.length-3) + return false; + + int lenR = signature[3] & 0xff; + if (5 + lenR >= signature.length || lenR == 0) + return false; + int lenS = signature[5+lenR] & 0xff; + if (lenR + lenS + 7 != signature.length || lenS == 0) + return false; + + // R value type mismatch R value negative + if (signature[4-2] != 0x02 || (signature[4] & 0x80) == 0x80) + return false; + if (lenR > 1 && signature[4] == 0x00 && (signature[4+1] & 0x80) != 0x80) + return false; // R value excessively padded + + // S value type mismatch S value negative + if (signature[6 + lenR - 2] != 0x02 || (signature[6 + lenR] & 0x80) == 0x80) + return false; + if (lenS > 1 && signature[6 + lenR] == 0x00 && (signature[6 + lenR + 1] & 0x80) != 0x80) + return false; // S value excessively padded + + return true; + } +} diff --git a/src/main/java/com/sparrowwallet/drongo/crypto/ECKey.java b/src/main/java/com/sparrowwallet/drongo/crypto/ECKey.java index 5922d11..37f9900 100644 --- a/src/main/java/com/sparrowwallet/drongo/crypto/ECKey.java +++ b/src/main/java/com/sparrowwallet/drongo/crypto/ECKey.java @@ -1,10 +1,10 @@ package com.sparrowwallet.drongo.crypto; import com.sparrowwallet.drongo.Utils; -import com.sparrowwallet.drongo.protocol.ScriptType; -import com.sparrowwallet.drongo.protocol.Sha256Hash; -import com.sparrowwallet.drongo.protocol.SignatureDecodeException; -import com.sparrowwallet.drongo.protocol.VarInt; +import com.sparrowwallet.drongo.protocol.*; +import org.bitcoin.NativeSecp256k1; +import org.bitcoin.NativeSecp256k1Util; +import org.bitcoin.Secp256k1Context; import org.bouncycastle.asn1.*; import org.bouncycastle.asn1.x9.X9ECParameters; import org.bouncycastle.asn1.x9.X9IntegerConverter; @@ -19,7 +19,6 @@ import org.bouncycastle.crypto.params.ECPublicKeyParameters; import org.bouncycastle.crypto.signers.ECDSASigner; import org.bouncycastle.math.ec.*; import org.bouncycastle.math.ec.custom.sec.SecP256K1Curve; -import org.bouncycastle.util.Properties; import org.bouncycastle.util.encoders.Hex; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -64,21 +63,9 @@ import java.util.Objects; * this class so round-tripping preserves state. Unless you're working with old software or doing unusual things, you * can usually ignore the compressed/uncompressed distinction.

*/ -public class ECKey implements EncryptableItem { +public class ECKey { private static final Logger log = LoggerFactory.getLogger(ECKey.class); - /** Sorts oldest keys first, newest last. */ - public static final Comparator AGE_COMPARATOR = new Comparator() { - - @Override - public int compare(ECKey k1, ECKey k2) { - if (k1.creationTimeSeconds == k2.creationTimeSeconds) - return 0; - else - return k1.creationTimeSeconds > k2.creationTimeSeconds ? 1 : -1; - } - }; - // The parameters of the secp256k1 curve that Bitcoin uses. private static final X9ECParameters CURVE_PARAMS = CustomNamedCurves.getByName("secp256k1"); @@ -106,13 +93,6 @@ public class ECKey implements EncryptableItem { protected final BigInteger priv; protected final LazyECPoint pub; - // Creation time of the key in seconds since the epoch, or zero if the key was deserialized from a version that did - // not have this field. - protected long creationTimeSeconds; - - protected KeyCrypter keyCrypter; - protected EncryptedData encryptedPrivateKey; - private byte[] pubKeyHash; /** @@ -157,18 +137,6 @@ public class ECKey implements EncryptableItem { this.pub = pub; } - /** - * Constructs a key that has an encrypted private component. The given object wraps encrypted bytes and an - * initialization vector. Note that the key will not be decrypted during this call: the returned ECKey is - * unusable for signing unless a decryption key is supplied. - */ - public static ECKey fromEncrypted(EncryptedData encryptedPrivateKey, KeyCrypter crypter, byte[] pubKey) { - ECKey key = fromPublicOnly(pubKey); - key.encryptedPrivateKey = encryptedPrivateKey; - key.keyCrypter = crypter; - return key; - } - /** * Utility for compressing an elliptic curve point. Returns the same point if it's already compressed. * See the ECKey class docs for a discussion of point compression. @@ -266,11 +234,6 @@ public class ECKey implements EncryptableItem { return priv != null; } - /** Returns true if this key is watch only, meaning it has a public key but no private key. */ - public boolean isWatching() { - return isPubKeyOnly() && !isEncrypted(); - } - /** * Output this ECKey as an ASN.1 encoded private key, as understood by OpenSSL or used by Bitcoin Core * in its wallet storage format. @@ -372,166 +335,10 @@ public class ECKey implements EncryptableItem { } /** - * Groups the two components that make up a signature, and provides a way to encode to DER form, which is - * how ECDSA signatures are represented when embedded in other data structures in the Bitcoin protocol. The raw - * components can be useful for doing further EC maths on them. + * Signs the given hash and returns the R and S components as an ECDSASignature. */ - public static class ECDSASignature { - /** The two components of the signature. */ - public final BigInteger r, s; - - /** - * Constructs a signature with the given components. Does NOT automatically canonicalise the signature. - */ - public ECDSASignature(BigInteger r, BigInteger s) { - this.r = r; - this.s = s; - } - - /** - * Returns true if the S component is "low", that means it is below {@link ECKey#HALF_CURVE_ORDER}. See BIP62. - */ - public boolean isCanonical() { - return s.compareTo(HALF_CURVE_ORDER) <= 0; - } - - /** - * Will automatically adjust the S component to be less than or equal to half the curve order, if necessary. - * This is required because for every signature (r,s) the signature (r, -s (mod N)) is a valid signature of - * the same message. However, we dislike the ability to modify the bits of a Bitcoin transaction after it's - * been signed, as that violates various assumed invariants. Thus in future only one of those forms will be - * considered legal and the other will be banned. - */ - public ECDSASignature toCanonicalised() { - if (!isCanonical()) { - // The order of the curve is the number of valid points that exist on that curve. If S is in the upper - // half of the number of valid points, then bring it back to the lower half. Otherwise, imagine that - // N = 10 - // s = 8, so (-8 % 10 == 2) thus both (r, 8) and (r, 2) are valid solutions. - // 10 - 8 == 2, giving us always the latter solution, which is canonical. - return new ECDSASignature(r, CURVE.getN().subtract(s)); - } else { - return this; - } - } - - /** - * DER is an international standard for serializing data structures which is widely used in cryptography. - * It's somewhat like protocol buffers but less convenient. This method returns a standard DER encoding - * of the signature, as recognized by OpenSSL and other libraries. - */ - public byte[] encodeToDER() { - try { - return derByteStream().toByteArray(); - } catch (IOException e) { - throw new RuntimeException(e); // Cannot happen. - } - } - - /** - * @throws SignatureDecodeException if the signature is unparseable in some way. - */ - public static ECDSASignature decodeFromDER(byte[] bytes) throws SignatureDecodeException { - ASN1InputStream decoder = null; - try { - // BouncyCastle by default is strict about parsing ASN.1 integers. We relax this check, because some - // Bitcoin signatures would not parse. - Properties.setThreadOverride("org.bouncycastle.asn1.allow_unsafe_integer", true); - decoder = new ASN1InputStream(bytes); - final ASN1Primitive seqObj = decoder.readObject(); - if (seqObj == null) - throw new SignatureDecodeException("Reached past end of ASN.1 stream."); - if (!(seqObj instanceof DLSequence)) - throw new SignatureDecodeException("Read unexpected class: " + seqObj.getClass().getName()); - final DLSequence seq = (DLSequence) seqObj; - ASN1Integer r, s; - try { - r = (ASN1Integer) seq.getObjectAt(0); - s = (ASN1Integer) seq.getObjectAt(1); - } catch (ClassCastException e) { - throw new SignatureDecodeException(e); - } - // OpenSSL deviates from the DER spec by interpreting these values as unsigned, though they should not be - // Thus, we always use the positive versions. See: http://r6.ca/blog/20111119T211504Z.html - return new ECDSASignature(r.getPositiveValue(), s.getPositiveValue()); - } catch (IOException e) { - throw new SignatureDecodeException(e); - } finally { - if (decoder != null) - try { decoder.close(); } catch (IOException x) {} - Properties.removeThreadOverride("org.bouncycastle.asn1.allow_unsafe_integer"); - } - } - - protected ByteArrayOutputStream derByteStream() throws IOException { - // Usually 70-72 bytes. - ByteArrayOutputStream bos = new ByteArrayOutputStream(72); - DERSequenceGenerator seq = new DERSequenceGenerator(bos); - seq.addObject(new ASN1Integer(r)); - seq.addObject(new ASN1Integer(s)); - seq.close(); - return bos; - } - - protected boolean hasLowR() { - //A low R signature will have less than 71 bytes when encoded to DER - return toCanonicalised().encodeToDER().length < 71; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - ECDSASignature other = (ECDSASignature) o; - return r.equals(other.r) && s.equals(other.s); - } - - @Override - public int hashCode() { - return Objects.hash(r, s); - } - } - - /** - * Signs the given hash and returns the R and S components as BigIntegers. In the Bitcoin protocol, they are - * usually encoded using ASN.1 format, so you want {@link ECKey.ECDSASignature#toASN1()} - * instead. However sometimes the independent components can be useful, for instance, if you're going to do - * further EC maths on them. - * @throws KeyCrypterException if this ECKey doesn't have a private part. - */ - public ECDSASignature sign(Sha256Hash input) throws KeyCrypterException { - return sign(input, null); - } - - /** - * Signs the given hash and returns the R and S components as BigIntegers. In the Bitcoin protocol, they are - * usually encoded using DER format, so you want {@link ECKey.ECDSASignature#encodeToDER()} - * instead. However sometimes the independent components can be useful, for instance, if you're doing to do further - * EC maths on them. - * - * @param aesKey The AES key to use for decryption of the private key. If null then no decryption is required. - * @throws KeyCrypterException if there's something wrong with aesKey. - * @throws ECKey.MissingPrivateKeyException if this key cannot sign because it's pubkey only. - */ - public ECDSASignature sign(Sha256Hash input, Key aesKey) throws KeyCrypterException { - KeyCrypter crypter = getKeyCrypter(); - if (crypter != null) { - if (aesKey == null) { - throw new KeyIsEncryptedException(); - } - return decrypt(aesKey).sign(input); - } else { - // No decryption of private key required. - if (priv == null) { - throw new MissingPrivateKeyException(); - } - } - return doSign(input, priv); - } - - protected ECDSASignature doSign(Sha256Hash input, BigInteger privateKeyForSigning) { - if(privateKeyForSigning == null) { + public ECDSASignature signEcdsa(Sha256Hash input) { + if(priv == null) { throw new IllegalArgumentException("Private key cannot be null"); } @@ -539,7 +346,7 @@ public class ECKey implements EncryptableItem { Integer counter = null; do { ECDSASigner signer = new ECDSASigner(new HMacDSANonceKCalculator(new SHA256Digest(), counter)); - ECPrivateKeyParameters privKey = new ECPrivateKeyParameters(privateKeyForSigning, CURVE); + ECPrivateKeyParameters privKey = new ECPrivateKeyParameters(priv, CURVE); signer.init(true, privKey); BigInteger[] components = signer.generateSignature(input.getBytes()); signature = new ECDSASignature(components[0], components[1]).toCanonicalised(); @@ -550,80 +357,39 @@ public class ECKey implements EncryptableItem { } /** - *

Verifies the given ECDSA signature against the message bytes using the public key bytes.

- * - *

When using native ECDSA verification, data must be 32 bytes, and no element may be - * larger than 520 bytes.

- * - * @param data Hash of the data to verify. - * @param signature ASN.1 encoded signature. - * @param pub The public key bytes to use. + * Signs the given hash and returns the R and S components as a SchnorrSignature. */ - public static boolean verify(byte[] data, ECDSASignature signature, byte[] pub) { - ECDSASigner signer = new ECDSASigner(); - ECPublicKeyParameters params = new ECPublicKeyParameters(CURVE.getCurve().decodePoint(pub), CURVE); - signer.init(false, params); - try { - return signer.verifySignature(data, signature.r, signature.s); - } catch (NullPointerException e) { - // Bouncy Castle contains a bug that can cause NPEs given specially crafted signatures. Those signatures - // are inherently invalid/attack sigs so we just fail them here rather than crash the thread. - log.error("Caught NPE inside bouncy castle", e); - return false; + public SchnorrSignature signSchnorr(Sha256Hash input) { + if(priv == null) { + throw new IllegalArgumentException("Private key cannot be null"); } + + if(!Secp256k1Context.isEnabled()) { + throw new IllegalStateException("libsecp256k1 is not enabled"); + } + + try { + byte[] sigBytes = NativeSecp256k1.schnorrSign(input.getBytes(), priv.toByteArray(), null); + return SchnorrSignature.decode(sigBytes); + } catch(NativeSecp256k1Util.AssertFailException e) { + log.error("Error signing schnorr", e); + } + + return null; } /** - * Verifies the given ASN.1 encoded ECDSA signature against a hash using the public key. - * - * @param data Hash of the data to verify. - * @param signature ASN.1 encoded signature. - * @param pub The public key bytes to use. - * @throws SignatureDecodeException if the signature is unparseable in some way. + * Verifies the given TransactionSignature against the provided byte array using the public key. */ - public static boolean verify(byte[] data, byte[] signature, byte[] pub) throws SignatureDecodeException { - return verify(data, ECDSASignature.decodeFromDER(signature), pub); - } - - /** - * Verifies the given ASN.1 encoded ECDSA signature against a hash using the public key. - * - * @param hash Hash of the data to verify. - * @param signature ASN.1 encoded signature. - * @throws SignatureDecodeException if the signature is unparseable in some way. - */ - public boolean verify(byte[] hash, byte[] signature) throws SignatureDecodeException { - return ECKey.verify(hash, signature, getPubKey()); + public boolean verify(byte[] data, TransactionSignature signature) { + return signature.verify(data, this); } /** * Verifies the given R/S pair (signature) against a hash using the public key. */ - public boolean verify(Sha256Hash sigHash, ECDSASignature signature) { - return ECKey.verify(sigHash.getBytes(), signature, getPubKey()); - } - - /** - * Verifies the given ASN.1 encoded ECDSA signature against a hash using the public key, and throws an exception - * if the signature doesn't match - * @throws SignatureDecodeException if the signature is unparseable in some way. - * @throws java.security.SignatureException if the signature does not match. - */ - public void verifyOrThrow(byte[] hash, byte[] signature) throws SignatureDecodeException, SignatureException { - if (!verify(hash, signature)) { - throw new SignatureException(); - } - } - - /** - * Verifies the given R/S pair (signature) against a hash using the public key, and throws an exception - * if the signature doesn't match - * @throws java.security.SignatureException if the signature does not match. - */ - public void verifyOrThrow(Sha256Hash sigHash, ECDSASignature signature) throws SignatureException { - if (!ECKey.verify(sigHash.getBytes(), signature, getPubKey())) { - throw new SignatureException(); - } + public boolean verify(Sha256Hash sigHash, TransactionSignature signature) { + return verify(sigHash.getBytes(), signature); } public ECKey getTweakedOutputKey() { @@ -757,12 +523,11 @@ public class ECKey implements EncryptableItem { * encoded string. * * @throws IllegalStateException if this ECKey does not have the private part. - * @throws KeyCrypterException if this ECKey is encrypted and no AESKey is provided or it does not decrypt the ECKey. */ - public String signMessage(String message, ScriptType scriptType, Key aesKey) throws KeyCrypterException { + public String signMessage(String message, ScriptType scriptType) { byte[] data = formatMessageForSigning(message); Sha256Hash hash = Sha256Hash.twiceOf(data); - ECDSASignature sig = sign(hash, aesKey); + ECDSASignature sig = signEcdsa(hash); byte recId = findRecoveryId(hash, sig); int headerByte = recId + getSigningTypeConstant(scriptType); byte[] sigData = new byte[65]; // 1 header + 32 bytes for R + 32 bytes for S @@ -981,181 +746,9 @@ public class ECKey implements EncryptableItem { } } - /** - * Returns the creation time of this key or zero if the key was deserialized from a version that did not store - * that data. - */ - @Override - public long getCreationTimeSeconds() { - return creationTimeSeconds; - } - - /** - * Sets the creation time of this key. Zero is a convention to mean "unavailable". This method can be useful when - * you have a raw key you are importing from somewhere else. - */ - public void setCreationTimeSeconds(long newCreationTimeSeconds) { - if (newCreationTimeSeconds < 0) { - throw new IllegalArgumentException("Cannot set creation time to negative value: " + newCreationTimeSeconds); - } - creationTimeSeconds = newCreationTimeSeconds; - } - - /** - * Create an encrypted private key with the keyCrypter and the AES key supplied. - * This method returns a new encrypted key and leaves the original unchanged. - * - * @param keyCrypter The keyCrypter that specifies exactly how the encrypted bytes are created. - * @param aesKey The Key with the AES encryption key (usually constructed with keyCrypter#deriveKey and cached as it is slow to create). - * @return encryptedKey - */ - public ECKey encrypt(KeyCrypter keyCrypter, Key aesKey) throws KeyCrypterException { - if(keyCrypter == null) { - throw new KeyCrypterException("Keycrypter cannot be null"); - } - - final byte[] privKeyBytes = getPrivKeyBytes(); - EncryptedData encryptedPrivateKey = keyCrypter.encrypt(privKeyBytes, null, aesKey); - ECKey result = ECKey.fromEncrypted(encryptedPrivateKey, keyCrypter, getPubKey()); - result.setCreationTimeSeconds(creationTimeSeconds); - return result; - } - - /** - * Create a decrypted private key with the keyCrypter and AES key supplied. Note that if the aesKey is wrong, this - * has some chance of throwing KeyCrypterException due to the corrupted padding that will result, but it can also - * just yield a garbage key. - * - * @param keyCrypter The keyCrypter that specifies exactly how the decrypted bytes are created. - * @param aesKey The Key with the AES encryption key (usually constructed with keyCrypter#deriveKey and cached). - */ - public ECKey decrypt(KeyCrypter keyCrypter, Key aesKey) throws KeyCrypterException { - if(keyCrypter == null) { - throw new KeyCrypterException("Keycrypter cannot be null"); - } - - // Check that the keyCrypter matches the one used to encrypt the keys, if set. - if (this.keyCrypter != null && !this.keyCrypter.equals(keyCrypter)) { - throw new KeyCrypterException("The keyCrypter being used to decrypt the key is different to the one that was used to encrypt it"); - } - - if(encryptedPrivateKey == null) { - throw new IllegalArgumentException("This key is not encrypted"); - } - - byte[] unencryptedPrivateKey = keyCrypter.decrypt(encryptedPrivateKey, aesKey); - ECKey key = ECKey.fromPrivate(unencryptedPrivateKey); - - if (!Arrays.equals(key.getPubKey(), getPubKey())) { - throw new KeyCrypterException("Provided AES key is wrong"); - } - - key.setCreationTimeSeconds(creationTimeSeconds); - return key; - } - - /** - * Create a decrypted private key with AES key. Note that if the AES key is wrong, this - * has some chance of throwing KeyCrypterException due to the corrupted padding that will result, but it can also - * just yield a garbage key. - * - * @param aesKey The Key with the AES encryption key (usually constructed with keyCrypter#deriveKey and cached). - */ - public ECKey decrypt(Key aesKey) throws KeyCrypterException { - final KeyCrypter crypter = getKeyCrypter(); - if (crypter == null) { - throw new KeyCrypterException("No key crypter available"); - } - - return decrypt(crypter, aesKey); - } - - /** - * Creates decrypted private key if needed. - */ - public ECKey maybeDecrypt(Key aesKey) throws KeyCrypterException { - return isEncrypted() && aesKey != null ? decrypt(aesKey) : this; - } - - /** - *

Check that it is possible to decrypt the key with the keyCrypter and that the original key is returned.

- * - *

Because it is a critical failure if the private keys cannot be decrypted successfully (resulting of loss of all - * bitcoins controlled by the private key) you can use this method to check when you *encrypt* a wallet that - * it can definitely be decrypted successfully.

- * - * @return true if the encrypted key can be decrypted back to the original key successfully. - */ - public static boolean encryptionIsReversible(ECKey originalKey, ECKey encryptedKey, KeyCrypter keyCrypter, Key aesKey) { - try { - ECKey rebornUnencryptedKey = encryptedKey.decrypt(keyCrypter, aesKey); - byte[] originalPrivateKeyBytes = originalKey.getPrivKeyBytes(); - byte[] rebornKeyBytes = rebornUnencryptedKey.getPrivKeyBytes(); - if (!Arrays.equals(originalPrivateKeyBytes, rebornKeyBytes)) { - log.error("The check that encryption could be reversed failed for {}", originalKey); - return false; - } - return true; - } catch (KeyCrypterException kce) { - log.error(kce.getMessage()); - return false; - } - } - - /** - * Indicates whether the private key is encrypted (true) or not (false). - * A private key is deemed to be encrypted when there is both a KeyCrypter and the encryptedPrivateKey is non-zero. - */ - @Override - public boolean isEncrypted() { - return keyCrypter != null && encryptedPrivateKey != null && encryptedPrivateKey.getEncryptedBytes().length > 0; - } - - @Override - public EncryptionType getEncryptionType() { - return new EncryptionType(EncryptionType.Deriver.SCRYPT, keyCrypter != null ? keyCrypter.getCrypterType() : EncryptionType.Crypter.NONE); - } - - /** - * A wrapper for {@link #getPrivKeyBytes()} that returns null if the private key bytes are missing or would have - * to be derived (for the HD key case). - */ - @Override - public byte[] getSecretBytes() { - if (hasPrivKey()) { - return getPrivKeyBytes(); - } else { - return null; - } - } - - /** An alias for {@link #getEncryptedPrivateKey()} */ - @Override - public EncryptedData getEncryptedData() { - return getEncryptedPrivateKey(); - } - - /** - * Returns the the encrypted private key bytes and initialisation vector for this ECKey, or null if the ECKey - * is not encrypted. - */ - public EncryptedData getEncryptedPrivateKey() { - return encryptedPrivateKey; - } - - /** - * Returns the KeyCrypter that was used to encrypt to encrypt this ECKey. You need this to decrypt the ECKey. - */ - public KeyCrypter getKeyCrypter() { - return keyCrypter; - } - public static class MissingPrivateKeyException extends RuntimeException { } - public static class KeyIsEncryptedException extends MissingPrivateKeyException { - } - @Override public boolean equals(Object o) { if (this == o) return true; diff --git a/src/main/java/com/sparrowwallet/drongo/crypto/SchnorrSignature.java b/src/main/java/com/sparrowwallet/drongo/crypto/SchnorrSignature.java new file mode 100644 index 0000000..100db0c --- /dev/null +++ b/src/main/java/com/sparrowwallet/drongo/crypto/SchnorrSignature.java @@ -0,0 +1,80 @@ +package com.sparrowwallet.drongo.crypto; + +import com.sparrowwallet.drongo.Utils; +import com.sparrowwallet.drongo.protocol.TransactionSignature; +import org.bitcoin.NativeSecp256k1; +import org.bitcoin.NativeSecp256k1Util; +import org.bitcoin.Secp256k1Context; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.math.BigInteger; +import java.nio.ByteBuffer; +import java.util.Arrays; + +/** + * Groups the two components that make up a Schnorr signature + */ +public class SchnorrSignature { + private static final Logger log = LoggerFactory.getLogger(SchnorrSignature.class); + + /** + * The two components of the signature. + */ + public final BigInteger r, s; + + /** + * Constructs a signature with the given components. Does NOT automatically canonicalise the signature. + */ + public SchnorrSignature(BigInteger r, BigInteger s) { + this.r = r; + this.s = s; + } + + public byte[] encode() { + ByteBuffer buffer = ByteBuffer.allocate(64); + buffer.put(Utils.bigIntegerToBytes(r, 32)); + buffer.put(Utils.bigIntegerToBytes(s, 32)); + return buffer.array(); + } + + public static SchnorrSignature decode(byte[] bytes) { + if(bytes.length != 64) { + throw new IllegalArgumentException("Invalid Schnorr signature length of " + bytes.length + " bytes"); + } + + BigInteger r = new BigInteger(1, Arrays.copyOfRange(bytes, 0, 32)); + BigInteger s = new BigInteger(1, Arrays.copyOfRange(bytes, 32, 64)); + + return new SchnorrSignature(r, s); + } + + public static TransactionSignature decodeFromBitcoin(byte[] bytes) { + if(bytes.length < 64 || bytes.length > 65) { + throw new IllegalArgumentException("Invalid Schnorr signature length of " + bytes.length + " bytes"); + } + + BigInteger r = new BigInteger(1, Arrays.copyOfRange(bytes, 0, 32)); + BigInteger s = new BigInteger(1, Arrays.copyOfRange(bytes, 32, 64)); + + if(bytes.length == 65) { + return new TransactionSignature(r, s, TransactionSignature.Type.SCHNORR, bytes[64]); + } + + return new TransactionSignature(r, s, TransactionSignature.Type.SCHNORR, (byte)0); + } + + public boolean verify(byte[] data, byte[] pub) { + if(!Secp256k1Context.isEnabled()) { + throw new IllegalStateException("libsecp256k1 is not enabled"); + } + + try { + return NativeSecp256k1.schnorrVerify(encode(), data, pub); + } catch(NativeSecp256k1Util.AssertFailException e) { + log.error("Error verifying schnorr signature", e); + } + + return false; + } +} diff --git a/src/main/java/com/sparrowwallet/drongo/protocol/ScriptChunk.java b/src/main/java/com/sparrowwallet/drongo/protocol/ScriptChunk.java index 5a2e015..f74b4d4 100644 --- a/src/main/java/com/sparrowwallet/drongo/protocol/ScriptChunk.java +++ b/src/main/java/com/sparrowwallet/drongo/protocol/ScriptChunk.java @@ -110,8 +110,8 @@ public class ScriptChunk { } try { - ECKey.ECDSASignature.decodeFromDER(data); - } catch(SignatureDecodeException e) { + TransactionSignature.decodeFromBitcoin(data, false); + } catch(Exception e) { return false; } @@ -120,7 +120,7 @@ public class ScriptChunk { public TransactionSignature getSignature() { try { - return TransactionSignature.decodeFromBitcoin(data, false, false); + return TransactionSignature.decodeFromBitcoin(data, false); } catch(SignatureDecodeException e) { throw new ProtocolException("Could not decode signature", e); } diff --git a/src/main/java/com/sparrowwallet/drongo/protocol/ScriptType.java b/src/main/java/com/sparrowwallet/drongo/protocol/ScriptType.java index 81a799f..c44e70d 100644 --- a/src/main/java/com/sparrowwallet/drongo/protocol/ScriptType.java +++ b/src/main/java/com/sparrowwallet/drongo/protocol/ScriptType.java @@ -126,6 +126,11 @@ public enum ScriptType { throw new ProtocolException(getName() + " is not a multisig script type"); } + @Override + public TransactionSignature.Type getSignatureType() { + return TransactionSignature.Type.ECDSA; + }; + @Override public List getAllowedPolicyTypes() { return List.of(SINGLE); @@ -239,6 +244,11 @@ public enum ScriptType { throw new ProtocolException(getName() + " is not a multisig script type"); } + @Override + public TransactionSignature.Type getSignatureType() { + return TransactionSignature.Type.ECDSA; + }; + @Override public List getAllowedPolicyTypes() { return List.of(SINGLE); @@ -425,6 +435,11 @@ public enum ScriptType { return transaction.addInput(prevOutput.getHash(), prevOutput.getIndex(), scriptSig); } + @Override + public TransactionSignature.Type getSignatureType() { + return TransactionSignature.Type.ECDSA; + }; + @Override public List getAllowedPolicyTypes() { return List.of(MULTI); @@ -550,6 +565,11 @@ public enum ScriptType { return transaction.addInput(prevOutput.getHash(), prevOutput.getIndex(), scriptSig); } + @Override + public TransactionSignature.Type getSignatureType() { + return TransactionSignature.Type.ECDSA; + }; + @Override public List getAllowedPolicyTypes() { return List.of(MULTI); @@ -653,6 +673,11 @@ public enum ScriptType { throw new ProtocolException(getName() + " is not a multisig script type"); } + @Override + public TransactionSignature.Type getSignatureType() { + return TransactionSignature.Type.ECDSA; + }; + @Override public List getAllowedPolicyTypes() { return List.of(SINGLE); @@ -754,6 +779,11 @@ public enum ScriptType { return transaction.addInput(prevOutput.getHash(), prevOutput.getIndex(), scriptSig, witness); } + @Override + public TransactionSignature.Type getSignatureType() { + return TransactionSignature.Type.ECDSA; + }; + @Override public List getAllowedPolicyTypes() { return List.of(MULTI, CUSTOM); @@ -859,6 +889,11 @@ public enum ScriptType { throw new ProtocolException(getName() + " is not a multisig script type"); } + @Override + public TransactionSignature.Type getSignatureType() { + return TransactionSignature.Type.ECDSA; + }; + @Override public List getAllowedPolicyTypes() { return List.of(SINGLE); @@ -970,6 +1005,11 @@ public enum ScriptType { return transaction.addInput(prevOutput.getHash(), prevOutput.getIndex(), scriptSig, witness); } + @Override + public TransactionSignature.Type getSignatureType() { + return TransactionSignature.Type.ECDSA; + }; + @Override public List getAllowedPolicyTypes() { return List.of(MULTI, CUSTOM); @@ -1078,6 +1118,11 @@ public enum ScriptType { throw new UnsupportedOperationException("Constructing Taproot inputs is not yet supported"); } + @Override + public TransactionSignature.Type getSignatureType() { + return TransactionSignature.Type.SCHNORR; + }; + @Override public List getAllowedPolicyTypes() { return Network.get() == Network.REGTEST || Network.get() == Network.SIGNET ? List.of(SINGLE) : Collections.emptyList(); @@ -1195,6 +1240,8 @@ public enum ScriptType { public abstract TransactionInput addMultisigSpendingInput(Transaction transaction, TransactionOutput prevOutput, int threshold, Map pubKeySignatures); + public abstract TransactionSignature.Type getSignatureType(); + public static final ScriptType[] SINGLE_KEY_TYPES = {P2PK, P2TR}; public static final ScriptType[] SINGLE_HASH_TYPES = {P2PKH, P2SH, P2SH_P2WPKH, P2SH_P2WSH, P2WPKH, P2WSH}; diff --git a/src/main/java/com/sparrowwallet/drongo/protocol/SigHash.java b/src/main/java/com/sparrowwallet/drongo/protocol/SigHash.java index 97ea175..9d5c44f 100644 --- a/src/main/java/com/sparrowwallet/drongo/protocol/SigHash.java +++ b/src/main/java/com/sparrowwallet/drongo/protocol/SigHash.java @@ -12,7 +12,7 @@ public enum SigHash { ANYONECANPAY_ALL("All + Anyone Can Pay", (byte)0x81), ANYONECANPAY_NONE("None + Anyone Can Pay", (byte)0x82), ANYONECANPAY_SINGLE("Single + Anyone Can Pay", (byte)0x83), - UNSET("Unset", (byte)0); // Caution: Using this type in isolation is non-standard. Treated similar to ALL. + ALL_TAPROOT("All (Taproot)", (byte)0); private final String name; public final byte value; diff --git a/src/main/java/com/sparrowwallet/drongo/protocol/TransactionSignature.java b/src/main/java/com/sparrowwallet/drongo/protocol/TransactionSignature.java index 86714bd..3e9fb1f 100644 --- a/src/main/java/com/sparrowwallet/drongo/protocol/TransactionSignature.java +++ b/src/main/java/com/sparrowwallet/drongo/protocol/TransactionSignature.java @@ -1,13 +1,19 @@ package com.sparrowwallet.drongo.protocol; +import com.sparrowwallet.drongo.crypto.ECDSASignature; import com.sparrowwallet.drongo.crypto.ECKey; +import com.sparrowwallet.drongo.crypto.SchnorrSignature; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.math.BigInteger; +import java.nio.ByteBuffer; import java.util.Objects; -public class TransactionSignature extends ECKey.ECDSASignature { +public class TransactionSignature { + private final ECDSASignature ecdsaSignature; + private final SchnorrSignature schnorrSignature; + /** * A byte that controls which parts of a transaction are signed. This is exposed because signatures * parsed off the wire may have sighash flags that aren't "normal" serializations of the enum values. @@ -16,21 +22,26 @@ public class TransactionSignature extends ECKey.ECDSASignature { */ public final byte sighashFlags; - /** Constructs a signature with the given components and SIGHASH_ALL. */ - public TransactionSignature(BigInteger r, BigInteger s) { - this(r, s, SigHash.ALL.value); - } - - /** Constructs a signature with the given components and raw sighash flag bytes (needed for rule compatibility). */ - public TransactionSignature(BigInteger r, BigInteger s, byte sighashFlags) { - super(r, s); - this.sighashFlags = sighashFlags; + /** Constructs a signature with the given components of the given type and SIGHASH_ALL. */ + public TransactionSignature(BigInteger r, BigInteger s, Type type) { + this(r, s, type, SigHash.ALL.value); } /** Constructs a transaction signature based on the ECDSA signature. */ - public TransactionSignature(ECKey.ECDSASignature signature, SigHash sigHash) { - super(signature.r, signature.s); - sighashFlags = sigHash.value; + public TransactionSignature(ECDSASignature signature, SigHash sigHash) { + this(signature.r, signature.s, Type.ECDSA, sigHash.value); + } + + /** Constructs a transaction signature based on the Schnorr signature. */ + public TransactionSignature(SchnorrSignature signature, SigHash sigHash) { + this(signature.r, signature.s, Type.SCHNORR, sigHash.value); + } + + /** Constructs a signature with the given components, type and raw sighash flag bytes (needed for rule compatibility). */ + public TransactionSignature(BigInteger r, BigInteger s, Type type, byte sighashFlags) { + ecdsaSignature = type == Type.ECDSA ? new ECDSASignature(r, s) : null; + schnorrSignature = type == Type.SCHNORR ? new SchnorrSignature(r, s) : null; + this.sighashFlags = sighashFlags; } /** @@ -39,61 +50,9 @@ public class TransactionSignature extends ECKey.ECDSASignature { * right size (e.g. for fee calculations) but don't have the requisite signing key yet and will fill out the * real signature later. */ - public static TransactionSignature dummy() { + public static TransactionSignature dummy(Type type) { BigInteger val = ECKey.HALF_CURVE_ORDER; - return new TransactionSignature(val, val); - } - - /** - * Returns true if the given signature is has canonical encoding, and will thus be accepted as standard by - * Bitcoin Core. DER and the SIGHASH encoding allow for quite some flexibility in how the same structures - * are encoded, and this can open up novel attacks in which a man in the middle takes a transaction and then - * changes its signature such that the transaction hash is different but it's still valid. This can confuse wallets - * and generally violates people's mental model of how Bitcoin should work, thus, non-canonical signatures are now - * not relayed by default. - */ - public static boolean isEncodingCanonical(byte[] signature) { - // See Bitcoin Core's IsCanonicalSignature, https://bitcointalk.org/index.php?topic=8392.msg127623#msg127623 - // A canonical signature exists of: <30> <02> <02> - // Where R and S are not negative (their first byte has its highest bit not set), and not - // excessively padded (do not start with a 0 byte, unless an otherwise negative number follows, - // in which case a single 0 byte is necessary and even required). - - // Empty signatures, while not strictly DER encoded, are allowed. - if (signature.length == 0) - return true; - - if (signature.length < 9 || signature.length > 73) - return false; - - int hashType = (signature[signature.length-1] & 0xff) & ~SigHash.ANYONECANPAY.value; // mask the byte to prevent sign-extension hurting us - if (hashType < SigHash.ALL.value || hashType > SigHash.SINGLE.value) - return false; - - // "wrong type" "wrong length marker" - if ((signature[0] & 0xff) != 0x30 || (signature[1] & 0xff) != signature.length-3) - return false; - - int lenR = signature[3] & 0xff; - if (5 + lenR >= signature.length || lenR == 0) - return false; - int lenS = signature[5+lenR] & 0xff; - if (lenR + lenS + 7 != signature.length || lenS == 0) - return false; - - // R value type mismatch R value negative - if (signature[4-2] != 0x02 || (signature[4] & 0x80) == 0x80) - return false; - if (lenR > 1 && signature[4] == 0x00 && (signature[4+1] & 0x80) != 0x80) - return false; // R value excessively padded - - // S value type mismatch S value negative - if (signature[6 + lenR - 2] != 0x02 || (signature[6 + lenR] & 0x80) == 0x80) - return false; - if (lenS > 1 && signature[6 + lenR] == 0x00 && (signature[6 + lenR + 1] & 0x80) != 0x80) - return false; // S value excessively padded - - return true; + return new TransactionSignature(val, val, type); } public boolean anyoneCanPay() { @@ -118,18 +77,51 @@ public class TransactionSignature extends ECKey.ECDSASignature { * components into a structure, and then we append a byte to the end for the sighash flags. */ public byte[] encodeToBitcoin() { - try { - ByteArrayOutputStream bos = derByteStream(); - bos.write(sighashFlags); - return bos.toByteArray(); - } catch (IOException e) { - throw new RuntimeException(e); // Cannot happen. + if(ecdsaSignature != null) { + try { + ByteArrayOutputStream bos = ecdsaSignature.derByteStream(); + bos.write(sighashFlags); + return bos.toByteArray(); + } catch (IOException e) { + throw new RuntimeException(e); // Cannot happen. + } + } else if(schnorrSignature != null) { + SigHash sigHash = getSigHash(); + ByteBuffer buffer = ByteBuffer.allocate(sigHash == SigHash.ALL ? 64 : 65); + buffer.put(schnorrSignature.encode()); + if(sigHash != SigHash.ALL) { + buffer.put(sighashFlags); + } + return buffer.array(); } + + throw new IllegalStateException("TransactionSignature has no values"); } - @Override - public ECKey.ECDSASignature toCanonicalised() { - return new TransactionSignature(super.toCanonicalised(), getSigHash()); + public static TransactionSignature decodeFromBitcoin(byte[] bytes, boolean requireCanonicalEncoding) throws SignatureDecodeException { + if(bytes.length == 64 || bytes.length == 65) { + return decodeFromBitcoin(Type.SCHNORR, bytes, requireCanonicalEncoding); + } + + return decodeFromBitcoin(Type.ECDSA, bytes, requireCanonicalEncoding); + } + + public static TransactionSignature decodeFromBitcoin(Type type, byte[] bytes, boolean requireCanonicalEncoding) throws SignatureDecodeException { + if(type == Type.ECDSA) { + return ECDSASignature.decodeFromBitcoin(bytes, requireCanonicalEncoding, false); + } else if(type == Type.SCHNORR) { + return SchnorrSignature.decodeFromBitcoin(bytes); + } + + throw new IllegalStateException("Unknown TransactionSignature type " + type); + } + + public boolean verify(byte[] data, ECKey pubKey) { + if(ecdsaSignature != null) { + return ecdsaSignature.verify(data, pubKey.getPubKey()); + } else { + return schnorrSignature.verify(data, pubKey.getPubKeyXCoord()); + } } @Override @@ -140,39 +132,16 @@ public class TransactionSignature extends ECKey.ECDSASignature { if(o == null || getClass() != o.getClass()) { return false; } - if(!super.equals(o)) { - return false; - } - TransactionSignature signature = (TransactionSignature) o; - return sighashFlags == signature.sighashFlags; + TransactionSignature that = (TransactionSignature) o; + return sighashFlags == that.sighashFlags && Objects.equals(ecdsaSignature, that.ecdsaSignature) && Objects.equals(schnorrSignature, that.schnorrSignature); } @Override public int hashCode() { - return Objects.hash(super.hashCode(), sighashFlags); + return Objects.hash(ecdsaSignature, schnorrSignature, sighashFlags); } - /** - * Returns a decoded signature. - * - * @param requireCanonicalEncoding if the encoding of the signature must - * be canonical. - * @param requireCanonicalSValue if the S-value must be canonical (below half - * the order of the curve). - * @throws SignatureDecodeException if the signature is unparseable in some way. - * @throws VerificationException if the signature is invalid. - */ - public static TransactionSignature decodeFromBitcoin(byte[] bytes, boolean requireCanonicalEncoding, - boolean requireCanonicalSValue) throws SignatureDecodeException, VerificationException { - // Bitcoin encoding is DER signature + sighash byte. - if (requireCanonicalEncoding && !isEncodingCanonical(bytes)) - throw new VerificationException.NoncanonicalSignature(); - ECKey.ECDSASignature sig = ECKey.ECDSASignature.decodeFromDER(bytes); - if (requireCanonicalSValue && !sig.isCanonical()) - throw new VerificationException("S-value is not canonical."); - - // In Bitcoin, any value of the final byte is valid, but not necessarily canonical. See javadocs for - // isEncodingCanonical to learn more about this. So we must store the exact byte found. - return new TransactionSignature(sig.r, sig.s, bytes[bytes.length - 1]); + public enum Type { + ECDSA, SCHNORR } } \ No newline at end of file diff --git a/src/main/java/com/sparrowwallet/drongo/psbt/PSBTInput.java b/src/main/java/com/sparrowwallet/drongo/psbt/PSBTInput.java index a569328..6d6e1cb 100644 --- a/src/main/java/com/sparrowwallet/drongo/psbt/PSBTInput.java +++ b/src/main/java/com/sparrowwallet/drongo/psbt/PSBTInput.java @@ -2,6 +2,7 @@ package com.sparrowwallet.drongo.psbt; import com.sparrowwallet.drongo.KeyDerivation; import com.sparrowwallet.drongo.Utils; +import com.sparrowwallet.drongo.crypto.ECDSASignature; import com.sparrowwallet.drongo.crypto.ECKey; import com.sparrowwallet.drongo.protocol.*; import org.slf4j.Logger; @@ -113,7 +114,7 @@ public class PSBTInput { entry.checkOneBytePlusPubKey(); ECKey sigPublicKey = ECKey.fromPublicOnly(entry.getKeyData()); //TODO: Verify signature - TransactionSignature signature = TransactionSignature.decodeFromBitcoin(entry.getData(), true, false); + TransactionSignature signature = TransactionSignature.decodeFromBitcoin(TransactionSignature.Type.ECDSA, entry.getData(), true); this.partialSignatures.put(sigPublicKey, signature); log.debug("Found input partial signature with public key " + sigPublicKey + " signature " + Utils.bytesToHex(entry.getData())); break; @@ -419,7 +420,7 @@ public class PSBTInput { Script signingScript = getSigningScript(); if(signingScript != null) { Sha256Hash hash = getHashForSignature(signingScript, localSigHash); - ECKey.ECDSASignature ecdsaSignature = privKey.sign(hash); + ECDSASignature ecdsaSignature = privKey.signEcdsa(hash); TransactionSignature transactionSignature = new TransactionSignature(ecdsaSignature, localSigHash); ECKey pubKey = ECKey.fromPublicOnly(privKey); diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java index 5d4344f..4dbb451 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java @@ -475,14 +475,14 @@ public class Wallet extends Persistable { TransactionInput txInput = null; if(getPolicyType().equals(PolicyType.SINGLE)) { ECKey pubKey = getPubKey(receiveNode); - TransactionSignature signature = TransactionSignature.dummy(); + TransactionSignature signature = TransactionSignature.dummy(getScriptType().getSignatureType()); txInput = getScriptType().addSpendingInput(transaction, prevTxOut, pubKey, signature); } else if(getPolicyType().equals(PolicyType.MULTI)) { List pubKeys = getPubKeys(receiveNode); int threshold = getDefaultPolicy().getNumSignaturesRequired(); Map pubKeySignatures = new TreeMap<>(new ECKey.LexicographicECKeyComparator()); for(int i = 0; i < pubKeys.size(); i++) { - pubKeySignatures.put(pubKeys.get(i), i < threshold ? TransactionSignature.dummy() : null); + pubKeySignatures.put(pubKeys.get(i), i < threshold ? TransactionSignature.dummy(getScriptType().getSignatureType()) : null); } txInput = getScriptType().addMultisigSpendingInput(transaction, prevTxOut, threshold, pubKeySignatures); } @@ -618,13 +618,13 @@ public class Wallet extends Persistable { public TransactionInput addDummySpendingInput(Transaction transaction, WalletNode walletNode, TransactionOutput prevTxOut) { if(getPolicyType().equals(PolicyType.SINGLE)) { ECKey pubKey = getPubKey(walletNode); - return getScriptType().addSpendingInput(transaction, prevTxOut, pubKey, TransactionSignature.dummy()); + return getScriptType().addSpendingInput(transaction, prevTxOut, pubKey, TransactionSignature.dummy(getScriptType().getSignatureType())); } else if(getPolicyType().equals(PolicyType.MULTI)) { List pubKeys = getPubKeys(walletNode); int threshold = getDefaultPolicy().getNumSignaturesRequired(); Map pubKeySignatures = new TreeMap<>(new ECKey.LexicographicECKeyComparator()); for(int i = 0; i < pubKeys.size(); i++) { - pubKeySignatures.put(pubKeys.get(i), i < threshold ? TransactionSignature.dummy() : null); + pubKeySignatures.put(pubKeys.get(i), i < threshold ? TransactionSignature.dummy(getScriptType().getSignatureType()) : null); } return getScriptType().addMultisigSpendingInput(transaction, prevTxOut, threshold, pubKeySignatures); } else { diff --git a/src/test/java/com/sparrowwallet/drongo/crypto/ECKeyTest.java b/src/test/java/com/sparrowwallet/drongo/crypto/ECKeyTest.java index ecbeb1c..8fb8808 100644 --- a/src/test/java/com/sparrowwallet/drongo/crypto/ECKeyTest.java +++ b/src/test/java/com/sparrowwallet/drongo/crypto/ECKeyTest.java @@ -27,15 +27,15 @@ public class ECKeyTest { ECKey privKey = keystore.getKey(firstReceive); //1 attempt required for low R - String signature1 = privKey.signMessage("Test2", ScriptType.P2PKH, null); + String signature1 = privKey.signMessage("Test2", ScriptType.P2PKH); Assert.assertEquals("IHra0jSywF1TjIJ5uf7IDECae438cr4o3VmG6Ri7hYlDL+pUEXyUfwLwpiAfUQVqQFLgs6OaX0KsoydpuwRI71o=", signature1); //2 attempts required for low R - String signature2 = privKey.signMessage("Test", ScriptType.P2PKH, null); + String signature2 = privKey.signMessage("Test", ScriptType.P2PKH); Assert.assertEquals("IDgMx1ljPhLHlKUOwnO/jBIgK+K8n8mvDUDROzTgU8gOaPDMs+eYXJpNXXINUx5WpeV605p5uO6B3TzBVcvs478=", signature2); //3 attempts required for low R - String signature3 = privKey.signMessage("Test1", ScriptType.P2PKH, null); + String signature3 = privKey.signMessage("Test1", ScriptType.P2PKH); Assert.assertEquals("IEt/v9K95YVFuRtRtWaabPVwWOFv1FSA/e874I8ABgYMbRyVvHhSwLFz0RZuO87ukxDd4TOsRdofQwMEA90LCgI=", signature3); } } diff --git a/src/test/java/com/sparrowwallet/drongo/protocol/TransactionTest.java b/src/test/java/com/sparrowwallet/drongo/protocol/TransactionTest.java index a913f1f..3bce9ec 100644 --- a/src/test/java/com/sparrowwallet/drongo/protocol/TransactionTest.java +++ b/src/test/java/com/sparrowwallet/drongo/protocol/TransactionTest.java @@ -20,7 +20,7 @@ public class TransactionTest { ECKey pubKey = ECKey.fromPublicOnly(Utils.hexToBytes("025476c2e83188368da1ff3e292e7acafcdb3566bb0ad253f62fc70f07aeee6357")); Sha256Hash hash = transaction.hashForWitnessSignature(1, ScriptType.P2PKH.getOutputScript(pubKey.getPubKeyHash()),600000000L, SigHash.ALL); - TransactionSignature signature = TransactionSignature.decodeFromBitcoin(Utils.hexToBytes("304402203609e17b84f6a7d30c80bfa610b5b4542f32a8a0d5447a12fb1366d7f01cc44a0220573a954c4518331561406f90300e8f3358f51928d43c212a8caed02de67eebee"), false, true); + TransactionSignature signature = TransactionSignature.decodeFromBitcoin(Utils.hexToBytes("304402203609e17b84f6a7d30c80bfa610b5b4542f32a8a0d5447a12fb1366d7f01cc44a0220573a954c4518331561406f90300e8f3358f51928d43c212a8caed02de67eebee"), false); Assert.assertTrue(pubKey.verify(hash, signature)); } @@ -31,7 +31,7 @@ public class TransactionTest { ECKey pubKey = ECKey.fromPublicOnly(Utils.hexToBytes("03ad1d8e89212f0b92c74d23bb710c00662ad1470198ac48c43f7d6f93a2a26873")); Sha256Hash hash = transaction.hashForWitnessSignature(0, ScriptType.P2PKH.getOutputScript(pubKey.getPubKeyHash()),1000000000L, SigHash.ALL); - TransactionSignature signature = TransactionSignature.decodeFromBitcoin(Utils.hexToBytes("3044022047ac8e878352d3ebbde1c94ce3a10d057c24175747116f8288e5d794d12d482f0220217f36a485cae903c713331d877c1f64677e3622ad4010726870540656fe9dcb01"), true, true); + TransactionSignature signature = TransactionSignature.decodeFromBitcoin(Utils.hexToBytes("3044022047ac8e878352d3ebbde1c94ce3a10d057c24175747116f8288e5d794d12d482f0220217f36a485cae903c713331d877c1f64677e3622ad4010726870540656fe9dcb01"), true); Assert.assertTrue(pubKey.verify(hash, signature)); } @@ -43,7 +43,7 @@ public class TransactionTest { ECKey pubKey = ECKey.fromPublicOnly(Utils.hexToBytes("026dccc749adc2a9d0d89497ac511f760f45c47dc5ed9cf352a58ac706453880ae")); Script script = new Script(Utils.hexToBytes("21026dccc749adc2a9d0d89497ac511f760f45c47dc5ed9cf352a58ac706453880aeadab210255a9626aebf5e29c0e6538428ba0d1dcf6ca98ffdf086aa8ced5e0d0215ea465ac")); Sha256Hash hash = transaction.hashForWitnessSignature(1, script,4900000000L, SigHash.SINGLE); - TransactionSignature signature = TransactionSignature.decodeFromBitcoin(Utils.hexToBytes("3044022027dc95ad6b740fe5129e7e62a75dd00f291a2aeb1200b84b09d9e3789406b6c002201a9ecd315dd6a0e632ab20bbb98948bc0c6fb204f2c286963bb48517a7058e2703"), true, true); + TransactionSignature signature = TransactionSignature.decodeFromBitcoin(Utils.hexToBytes("3044022027dc95ad6b740fe5129e7e62a75dd00f291a2aeb1200b84b09d9e3789406b6c002201a9ecd315dd6a0e632ab20bbb98948bc0c6fb204f2c286963bb48517a7058e2703"), true); Assert.assertTrue(pubKey.verify(hash, signature)); } @@ -55,7 +55,7 @@ public class TransactionTest { ECKey pubKey = ECKey.fromPublicOnly(Utils.hexToBytes("0392972e2eb617b2388771abe27235fd5ac44af8e61693261550447a4c3e39da98")); Script script = new Script(Utils.hexToBytes("68210392972e2eb617b2388771abe27235fd5ac44af8e61693261550447a4c3e39da98ac")); Sha256Hash hash = transaction.hashForWitnessSignature(1, script,16777215L, SigHash.ANYONECANPAY_SINGLE); - TransactionSignature signature = TransactionSignature.decodeFromBitcoin(Utils.hexToBytes("30440220032521802a76ad7bf74d0e2c218b72cf0cbc867066e2e53db905ba37f130397e02207709e2188ed7f08f4c952d9d13986da504502b8c3be59617e043552f506c46ff83"), true, true); + TransactionSignature signature = TransactionSignature.decodeFromBitcoin(Utils.hexToBytes("30440220032521802a76ad7bf74d0e2c218b72cf0cbc867066e2e53db905ba37f130397e02207709e2188ed7f08f4c952d9d13986da504502b8c3be59617e043552f506c46ff83"), true); Assert.assertTrue(pubKey.verify(hash, signature)); } @@ -67,7 +67,7 @@ public class TransactionTest { ECKey pubKey = ECKey.fromPublicOnly(Utils.hexToBytes("0307b8ae49ac90a048e9b53357a2354b3334e9c8bee813ecb98e99a7e07e8c3ba3")); Script script = new Script(Utils.hexToBytes("56210307b8ae49ac90a048e9b53357a2354b3334e9c8bee813ecb98e99a7e07e8c3ba32103b28f0c28bfab54554ae8c658ac5c3e0ce6e79ad336331f78c428dd43eea8449b21034b8113d703413d57761b8b9781957b8c0ac1dfe69f492580ca4195f50376ba4a21033400f6afecb833092a9a21cfdf1ed1376e58c5d1f47de74683123987e967a8f42103a6d48b1131e94ba04d9737d61acdaa1322008af9602b3b14862c07a1789aac162102d8b661b0b3302ee2f162b09e07a55ad5dfbe673a9f01d9f0c19617681024306b56ae")); Sha256Hash hash = transaction.hashForWitnessSignature(0, script,987654321L, SigHash.ALL); - TransactionSignature signature = TransactionSignature.decodeFromBitcoin(Utils.hexToBytes("304402206ac44d672dac41f9b00e28f4df20c52eeb087207e8d758d76d92c6fab3b73e2b0220367750dbbe19290069cba53d096f44530e4f98acaa594810388cf7409a1870ce01"), true, true); + TransactionSignature signature = TransactionSignature.decodeFromBitcoin(Utils.hexToBytes("304402206ac44d672dac41f9b00e28f4df20c52eeb087207e8d758d76d92c6fab3b73e2b0220367750dbbe19290069cba53d096f44530e4f98acaa594810388cf7409a1870ce01"), true); Assert.assertTrue(pubKey.verify(hash, signature)); } @@ -79,7 +79,7 @@ public class TransactionTest { ECKey pubKey = ECKey.fromPublicOnly(Utils.hexToBytes("03b28f0c28bfab54554ae8c658ac5c3e0ce6e79ad336331f78c428dd43eea8449b")); Script script = new Script(Utils.hexToBytes("56210307b8ae49ac90a048e9b53357a2354b3334e9c8bee813ecb98e99a7e07e8c3ba32103b28f0c28bfab54554ae8c658ac5c3e0ce6e79ad336331f78c428dd43eea8449b21034b8113d703413d57761b8b9781957b8c0ac1dfe69f492580ca4195f50376ba4a21033400f6afecb833092a9a21cfdf1ed1376e58c5d1f47de74683123987e967a8f42103a6d48b1131e94ba04d9737d61acdaa1322008af9602b3b14862c07a1789aac162102d8b661b0b3302ee2f162b09e07a55ad5dfbe673a9f01d9f0c19617681024306b56ae")); Sha256Hash hash = transaction.hashForWitnessSignature(0, script,987654321L, SigHash.NONE); - TransactionSignature signature = TransactionSignature.decodeFromBitcoin(Utils.hexToBytes("3044022068c7946a43232757cbdf9176f009a928e1cd9a1a8c212f15c1e11ac9f2925d9002205b75f937ff2f9f3c1246e547e54f62e027f64eefa2695578cc6432cdabce271502"), true, true); + TransactionSignature signature = TransactionSignature.decodeFromBitcoin(Utils.hexToBytes("3044022068c7946a43232757cbdf9176f009a928e1cd9a1a8c212f15c1e11ac9f2925d9002205b75f937ff2f9f3c1246e547e54f62e027f64eefa2695578cc6432cdabce271502"), true); Assert.assertTrue(pubKey.verify(hash, signature)); } @@ -91,7 +91,7 @@ public class TransactionTest { ECKey pubKey = ECKey.fromPublicOnly(Utils.hexToBytes("034b8113d703413d57761b8b9781957b8c0ac1dfe69f492580ca4195f50376ba4a")); Script script = new Script(Utils.hexToBytes("56210307b8ae49ac90a048e9b53357a2354b3334e9c8bee813ecb98e99a7e07e8c3ba32103b28f0c28bfab54554ae8c658ac5c3e0ce6e79ad336331f78c428dd43eea8449b21034b8113d703413d57761b8b9781957b8c0ac1dfe69f492580ca4195f50376ba4a21033400f6afecb833092a9a21cfdf1ed1376e58c5d1f47de74683123987e967a8f42103a6d48b1131e94ba04d9737d61acdaa1322008af9602b3b14862c07a1789aac162102d8b661b0b3302ee2f162b09e07a55ad5dfbe673a9f01d9f0c19617681024306b56ae")); Sha256Hash hash = transaction.hashForWitnessSignature(0, script,987654321L, SigHash.SINGLE); - TransactionSignature signature = TransactionSignature.decodeFromBitcoin(Utils.hexToBytes("3044022059ebf56d98010a932cf8ecfec54c48e6139ed6adb0728c09cbe1e4fa0915302e022007cd986c8fa870ff5d2b3a89139c9fe7e499259875357e20fcbb15571c76795403"), true, true); + TransactionSignature signature = TransactionSignature.decodeFromBitcoin(Utils.hexToBytes("3044022059ebf56d98010a932cf8ecfec54c48e6139ed6adb0728c09cbe1e4fa0915302e022007cd986c8fa870ff5d2b3a89139c9fe7e499259875357e20fcbb15571c76795403"), true); Assert.assertTrue(pubKey.verify(hash, signature)); } @@ -103,7 +103,7 @@ public class TransactionTest { ECKey pubKey = ECKey.fromPublicOnly(Utils.hexToBytes("033400f6afecb833092a9a21cfdf1ed1376e58c5d1f47de74683123987e967a8f4")); Script script = new Script(Utils.hexToBytes("56210307b8ae49ac90a048e9b53357a2354b3334e9c8bee813ecb98e99a7e07e8c3ba32103b28f0c28bfab54554ae8c658ac5c3e0ce6e79ad336331f78c428dd43eea8449b21034b8113d703413d57761b8b9781957b8c0ac1dfe69f492580ca4195f50376ba4a21033400f6afecb833092a9a21cfdf1ed1376e58c5d1f47de74683123987e967a8f42103a6d48b1131e94ba04d9737d61acdaa1322008af9602b3b14862c07a1789aac162102d8b661b0b3302ee2f162b09e07a55ad5dfbe673a9f01d9f0c19617681024306b56ae")); Sha256Hash hash = transaction.hashForWitnessSignature(0, script,987654321L, SigHash.ANYONECANPAY_ALL); - TransactionSignature signature = TransactionSignature.decodeFromBitcoin(Utils.hexToBytes("3045022100fbefd94bd0a488d50b79102b5dad4ab6ced30c4069f1eaa69a4b5a763414067e02203156c6a5c9cf88f91265f5a942e96213afae16d83321c8b31bb342142a14d16381"), true, true); + TransactionSignature signature = TransactionSignature.decodeFromBitcoin(Utils.hexToBytes("3045022100fbefd94bd0a488d50b79102b5dad4ab6ced30c4069f1eaa69a4b5a763414067e02203156c6a5c9cf88f91265f5a942e96213afae16d83321c8b31bb342142a14d16381"), true); Assert.assertTrue(pubKey.verify(hash, signature)); } @@ -115,7 +115,7 @@ public class TransactionTest { ECKey pubKey = ECKey.fromPublicOnly(Utils.hexToBytes("03a6d48b1131e94ba04d9737d61acdaa1322008af9602b3b14862c07a1789aac16")); Script script = new Script(Utils.hexToBytes("56210307b8ae49ac90a048e9b53357a2354b3334e9c8bee813ecb98e99a7e07e8c3ba32103b28f0c28bfab54554ae8c658ac5c3e0ce6e79ad336331f78c428dd43eea8449b21034b8113d703413d57761b8b9781957b8c0ac1dfe69f492580ca4195f50376ba4a21033400f6afecb833092a9a21cfdf1ed1376e58c5d1f47de74683123987e967a8f42103a6d48b1131e94ba04d9737d61acdaa1322008af9602b3b14862c07a1789aac162102d8b661b0b3302ee2f162b09e07a55ad5dfbe673a9f01d9f0c19617681024306b56ae")); Sha256Hash hash = transaction.hashForWitnessSignature(0, script,987654321L, SigHash.ANYONECANPAY_NONE); - TransactionSignature signature = TransactionSignature.decodeFromBitcoin(Utils.hexToBytes("3045022100a5263ea0553ba89221984bd7f0b13613db16e7a70c549a86de0cc0444141a407022005c360ef0ae5a5d4f9f2f87a56c1546cc8268cab08c73501d6b3be2e1e1a8a0882"), true, true); + TransactionSignature signature = TransactionSignature.decodeFromBitcoin(Utils.hexToBytes("3045022100a5263ea0553ba89221984bd7f0b13613db16e7a70c549a86de0cc0444141a407022005c360ef0ae5a5d4f9f2f87a56c1546cc8268cab08c73501d6b3be2e1e1a8a0882"), true); Assert.assertTrue(pubKey.verify(hash, signature)); } @@ -127,7 +127,7 @@ public class TransactionTest { ECKey pubKey = ECKey.fromPublicOnly(Utils.hexToBytes("02d8b661b0b3302ee2f162b09e07a55ad5dfbe673a9f01d9f0c19617681024306b")); Script script = new Script(Utils.hexToBytes("56210307b8ae49ac90a048e9b53357a2354b3334e9c8bee813ecb98e99a7e07e8c3ba32103b28f0c28bfab54554ae8c658ac5c3e0ce6e79ad336331f78c428dd43eea8449b21034b8113d703413d57761b8b9781957b8c0ac1dfe69f492580ca4195f50376ba4a21033400f6afecb833092a9a21cfdf1ed1376e58c5d1f47de74683123987e967a8f42103a6d48b1131e94ba04d9737d61acdaa1322008af9602b3b14862c07a1789aac162102d8b661b0b3302ee2f162b09e07a55ad5dfbe673a9f01d9f0c19617681024306b56ae")); Sha256Hash hash = transaction.hashForWitnessSignature(0, script,987654321L, SigHash.ANYONECANPAY_SINGLE); - TransactionSignature signature = TransactionSignature.decodeFromBitcoin(Utils.hexToBytes("30440220525406a1482936d5a21888260dc165497a90a15669636d8edca6b9fe490d309c022032af0c646a34a44d1f4576bf6a4a74b67940f8faa84c7df9abe12a01a11e2b4783"), true, true); + TransactionSignature signature = TransactionSignature.decodeFromBitcoin(Utils.hexToBytes("30440220525406a1482936d5a21888260dc165497a90a15669636d8edca6b9fe490d309c022032af0c646a34a44d1f4576bf6a4a74b67940f8faa84c7df9abe12a01a11e2b4783"), true); Assert.assertTrue(pubKey.verify(hash, signature)); } @@ -340,7 +340,7 @@ public class TransactionTest { TransactionInput input0 = spendingTransaction.getInputs().get(0); Script spendingScript = input0.getScriptSig(); TransactionWitness witness0 = input0.getWitness(); - TransactionSignature signature0 = TransactionSignature.decodeFromBitcoin(witness0.getPushes().get(0), false, false); + TransactionSignature signature0 = TransactionSignature.decodeFromBitcoin(witness0.getPushes().get(0), false); ECKey pubKey0 = ECKey.fromPublicOnly(witness0.getPushes().get(1)); Transaction transaction = new Transaction(); @@ -375,8 +375,8 @@ public class TransactionTest { TransactionInput input0 = spendingTransaction.getInputs().get(0); TransactionWitness witness0 = input0.getWitness(); - TransactionSignature signature0 = TransactionSignature.decodeFromBitcoin(witness0.getPushes().get(1), false, false); - TransactionSignature signature1 = TransactionSignature.decodeFromBitcoin(witness0.getPushes().get(2), false, false); + TransactionSignature signature0 = TransactionSignature.decodeFromBitcoin(witness0.getPushes().get(1), false); + TransactionSignature signature1 = TransactionSignature.decodeFromBitcoin(witness0.getPushes().get(2), false); Script witnessScript = new Script(witness0.getPushes().get(3)); ECKey key0 = witnessScript.getChunks().get(1).getPubKey(); ECKey key1 = witnessScript.getChunks().get(2).getPubKey(); @@ -417,7 +417,7 @@ public class TransactionTest { TransactionInput input0 = spendingTransaction.getInputs().get(0); TransactionWitness witness0 = input0.getWitness(); - TransactionSignature signature0 = TransactionSignature.decodeFromBitcoin(witness0.getPushes().get(0), false, false); + TransactionSignature signature0 = TransactionSignature.decodeFromBitcoin(witness0.getPushes().get(0), false); ECKey key0 = ECKey.fromPublicOnly(witness0.getPushes().get(1)); Transaction transaction = new Transaction(); @@ -451,8 +451,8 @@ public class TransactionTest { TransactionInput input0 = spendingTransaction.getInputs().get(0); TransactionWitness witness0 = input0.getWitness(); - TransactionSignature signature0 = TransactionSignature.decodeFromBitcoin(witness0.getPushes().get(1), false, false); - TransactionSignature signature1 = TransactionSignature.decodeFromBitcoin(witness0.getPushes().get(2), false, false); + TransactionSignature signature0 = TransactionSignature.decodeFromBitcoin(witness0.getPushes().get(1), false); + TransactionSignature signature1 = TransactionSignature.decodeFromBitcoin(witness0.getPushes().get(2), false); Script witnessScript = new Script(witness0.getPushes().get(3)); ECKey key0 = witnessScript.getChunks().get(1).getPubKey(); ECKey key1 = witnessScript.getChunks().get(2).getPubKey(); From c71979966bbdbff58b1f63946549b15f54890ab5 Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Wed, 14 Jul 2021 15:12:18 +0200 Subject: [PATCH 048/155] support taproot single key keypath spends --- .../java/com/sparrowwallet/drongo/Utils.java | 12 ++ .../sparrowwallet/drongo/crypto/ECKey.java | 42 ++++-- .../drongo/crypto/SchnorrSignature.java | 18 +++ .../drongo/protocol/ScriptType.java | 17 ++- .../drongo/protocol/Transaction.java | 121 ++++++++++++++++ .../drongo/protocol/TransactionSignature.java | 6 +- .../drongo/protocol/TransactionWitness.java | 6 + .../com/sparrowwallet/drongo/psbt/PSBT.java | 16 +- .../sparrowwallet/drongo/psbt/PSBTInput.java | 137 +++++++++++++++--- .../sparrowwallet/drongo/wallet/Wallet.java | 24 ++- .../drongo/protocol/TransactionTest.java | 24 +++ 11 files changed, 368 insertions(+), 55 deletions(-) diff --git a/src/main/java/com/sparrowwallet/drongo/Utils.java b/src/main/java/com/sparrowwallet/drongo/Utils.java index d45b9b3..f749d19 100644 --- a/src/main/java/com/sparrowwallet/drongo/Utils.java +++ b/src/main/java/com/sparrowwallet/drongo/Utils.java @@ -12,6 +12,8 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.math.BigInteger; +import java.nio.ByteBuffer; +import java.nio.charset.StandardCharsets; import java.util.*; public class Utils { @@ -289,6 +291,16 @@ public class Utils { return out; } + public static byte[] taggedHash(String tag, byte[] msg) { + byte[] hash = Sha256Hash.hash(tag.getBytes(StandardCharsets.UTF_8)); + ByteBuffer buffer = ByteBuffer.allocate(hash.length + hash.length + msg.length); + buffer.put(hash); + buffer.put(hash); + buffer.put(msg); + + return Sha256Hash.hash(buffer.array()); + } + public static class LexicographicByteArrayComparator implements Comparator { @Override public int compare(byte[] left, byte[] right) { diff --git a/src/main/java/com/sparrowwallet/drongo/crypto/ECKey.java b/src/main/java/com/sparrowwallet/drongo/crypto/ECKey.java index 37f9900..17f19cb 100644 --- a/src/main/java/com/sparrowwallet/drongo/crypto/ECKey.java +++ b/src/main/java/com/sparrowwallet/drongo/crypto/ECKey.java @@ -26,7 +26,6 @@ import org.slf4j.LoggerFactory; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.math.BigInteger; -import java.nio.ByteBuffer; import java.nio.charset.StandardCharsets; import java.security.SecureRandom; import java.security.SignatureException; @@ -369,7 +368,7 @@ public class ECKey { } try { - byte[] sigBytes = NativeSecp256k1.schnorrSign(input.getBytes(), priv.toByteArray(), null); + byte[] sigBytes = NativeSecp256k1.schnorrSign(input.getBytes(), Utils.bigIntegerToBytes(priv, 32), new byte[32]); return SchnorrSignature.decode(sigBytes); } catch(NativeSecp256k1Util.AssertFailException e) { log.error("Error signing schnorr", e); @@ -393,13 +392,28 @@ public class ECKey { } public ECKey getTweakedOutputKey() { - ECPoint internalKey = liftX(getPubKeyXCoord()); - byte[] taggedHash = taggedHash("TapTweak", internalKey.getXCoord().getEncoded()); - ECPoint outputKey = internalKey.add(ECKey.fromPrivate(taggedHash).getPubKeyPoint()); + TaprootPubKey taprootPubKey = liftX(getPubKeyXCoord()); + ECPoint internalKey = taprootPubKey.ecPoint; + byte[] taggedHash = Utils.taggedHash("TapTweak", internalKey.getXCoord().getEncoded()); + ECKey tweakValue = ECKey.fromPrivate(taggedHash); + ECPoint outputKey = internalKey.add(tweakValue.getPubKeyPoint()); + + if(hasPrivKey()) { + BigInteger taprootPriv = priv; + BigInteger tweakedPrivKey = taprootPriv.add(tweakValue.getPrivKey()).mod(CURVE_PARAMS.getCurve().getOrder()); + //TODO: Improve on this hack. How do we know whether to negate the private key before tweaking it? + if(!ECKey.fromPrivate(tweakedPrivKey).getPubKeyPoint().equals(outputKey)) { + taprootPriv = CURVE_PARAMS.getCurve().getOrder().subtract(priv); + tweakedPrivKey = taprootPriv.add(tweakValue.getPrivKey()).mod(CURVE_PARAMS.getCurve().getOrder()); + } + + return new ECKey(tweakedPrivKey, outputKey, true); + } + return ECKey.fromPublicOnly(outputKey, true); } - private static ECPoint liftX(byte[] bytes) { + private static TaprootPubKey liftX(byte[] bytes) { SecP256K1Curve secP256K1Curve = (SecP256K1Curve)CURVE_PARAMS.getCurve(); BigInteger x = new BigInteger(1, bytes); BigInteger p = secP256K1Curve.getQ(); @@ -413,17 +427,17 @@ public class ECKey { throw new IllegalStateException("Calculated invalid y_sq when solving for y co-ordinate"); } - return secP256K1Curve.createPoint(x, y.and(BigInteger.ONE).equals(BigInteger.ZERO) ? y : p.subtract(y)); + return y.and(BigInteger.ONE).equals(BigInteger.ZERO) ? new TaprootPubKey(secP256K1Curve.createPoint(x, y), false) : new TaprootPubKey(secP256K1Curve.createPoint(x, p.subtract(y)), true); } - private static byte[] taggedHash(String tag, byte[] msg) { - byte[] hash = Sha256Hash.hash(tag.getBytes(StandardCharsets.UTF_8)); - ByteBuffer buffer = ByteBuffer.allocate(hash.length + hash.length + msg.length); - buffer.put(hash); - buffer.put(hash); - buffer.put(msg); + private static class TaprootPubKey { + public final ECPoint ecPoint; + public final boolean negated; - return Sha256Hash.hash(buffer.array()); + public TaprootPubKey(ECPoint ecPoint, boolean negated) { + this.ecPoint = ecPoint; + this.negated = negated; + } } /** diff --git a/src/main/java/com/sparrowwallet/drongo/crypto/SchnorrSignature.java b/src/main/java/com/sparrowwallet/drongo/crypto/SchnorrSignature.java index 100db0c..92ddb7b 100644 --- a/src/main/java/com/sparrowwallet/drongo/crypto/SchnorrSignature.java +++ b/src/main/java/com/sparrowwallet/drongo/crypto/SchnorrSignature.java @@ -11,6 +11,7 @@ import org.slf4j.LoggerFactory; import java.math.BigInteger; import java.nio.ByteBuffer; import java.util.Arrays; +import java.util.Objects; /** * Groups the two components that make up a Schnorr signature @@ -77,4 +78,21 @@ public class SchnorrSignature { return false; } + + @Override + public boolean equals(Object o) { + if(this == o) { + return true; + } + if(o == null || getClass() != o.getClass()) { + return false; + } + SchnorrSignature that = (SchnorrSignature) o; + return r.equals(that.r) && s.equals(that.s); + } + + @Override + public int hashCode() { + return Objects.hash(r, s); + } } diff --git a/src/main/java/com/sparrowwallet/drongo/protocol/ScriptType.java b/src/main/java/com/sparrowwallet/drongo/protocol/ScriptType.java index c44e70d..3d8da30 100644 --- a/src/main/java/com/sparrowwallet/drongo/protocol/ScriptType.java +++ b/src/main/java/com/sparrowwallet/drongo/protocol/ScriptType.java @@ -1016,6 +1016,11 @@ public enum ScriptType { } }, P2TR("P2TR", "Taproot (P2TR)", "m/86'/0'/0'") { + @Override + public ECKey getOutputKey(ECKey derivedKey) { + return derivedKey.getTweakedOutputKey(); + } + @Override public Address getAddress(byte[] pubKey) { return new P2TRAddress(pubKey); @@ -1023,7 +1028,7 @@ public enum ScriptType { @Override public Address getAddress(ECKey derivedKey) { - return getAddress(derivedKey.getTweakedOutputKey().getPubKeyXCoord()); + return getAddress(getOutputKey(derivedKey).getPubKeyXCoord()); } @Override @@ -1042,7 +1047,7 @@ public enum ScriptType { @Override public Script getOutputScript(ECKey derivedKey) { - return getOutputScript(derivedKey.getTweakedOutputKey().getPubKeyXCoord()); + return getOutputScript(getOutputKey(derivedKey).getPubKeyXCoord()); } @Override @@ -1105,7 +1110,9 @@ public enum ScriptType { @Override public TransactionInput addSpendingInput(Transaction transaction, TransactionOutput prevOutput, ECKey pubKey, TransactionSignature signature) { - throw new UnsupportedOperationException("Constructing Taproot inputs is not yet supported"); + Script scriptSig = getScriptSig(prevOutput.getScript(), pubKey, signature); + TransactionWitness witness = new TransactionWitness(transaction, signature); + return transaction.addInput(prevOutput.getHash(), prevOutput.getIndex(), scriptSig, witness); } @Override @@ -1186,6 +1193,10 @@ public enum ScriptType { return getAllowedPolicyTypes().contains(policyType); } + public ECKey getOutputKey(ECKey derivedKey) { + return derivedKey; + } + public abstract Address getAddress(byte[] bytes); public abstract Address getAddress(ECKey key); diff --git a/src/main/java/com/sparrowwallet/drongo/protocol/Transaction.java b/src/main/java/com/sparrowwallet/drongo/protocol/Transaction.java index 59f24e0..fc86c24 100644 --- a/src/main/java/com/sparrowwallet/drongo/protocol/Transaction.java +++ b/src/main/java/com/sparrowwallet/drongo/protocol/Transaction.java @@ -31,6 +31,8 @@ public class Transaction extends ChildMessage { //Default min feerate, defined in sats/vByte public static final double DEFAULT_MIN_RELAY_FEE = 1d; + public static final byte LEAF_VERSION_TAPSCRIPT = (byte)0xc0; + private long version; private long locktime; private boolean segwit; @@ -609,4 +611,123 @@ public class Transaction extends ChildMessage { return Sha256Hash.twiceOf(bos.toByteArray()); } + + /** + *

Calculates a signature hash, that is, a hash of a simplified form of the transaction. How exactly the transaction + * is simplified is specified by the type and anyoneCanPay parameters.

+ * + * (See BIP341: https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki)

+ * + * @param spentUtxos the ordered list of spent UTXOs corresponding to the inputs of this transaction + * @param inputIndex input the signature is being calculated for. Tx signatures are always relative to an input. + * @param scriptPath whether we are signing for the keypath or the scriptpath + * @param script if signing for the scriptpath, the script to sign + * @param sigHash should usually be SigHash.ALL + * @param annex annex data + */ + public synchronized Sha256Hash hashForTaprootSignature(List spentUtxos, int inputIndex, boolean scriptPath, Script script, SigHash sigHash, byte[] annex) { + return hashForTaprootSignature(spentUtxos, inputIndex, scriptPath, script, sigHash.value, annex); + } + + public synchronized Sha256Hash hashForTaprootSignature(List spentUtxos, int inputIndex, boolean scriptPath, Script script, byte sigHashType, byte[] annex) { + if(spentUtxos.size() != getInputs().size()) { + throw new IllegalArgumentException("Provided spent UTXOs length does not equal the number of transaction inputs"); + } + if(inputIndex >= getInputs().size()) { + throw new IllegalArgumentException("Input index is greater than the number of transaction inputs"); + } + + ByteArrayOutputStream bos = new UnsafeByteArrayOutputStream(length == UNKNOWN_LENGTH ? 256 : length + 4); + try { + byte outType = sigHashType == 0x00 ? SigHash.ALL.value : (byte)(sigHashType & 0x03); + boolean anyoneCanPay = (sigHashType & SigHash.ANYONECANPAY.value) == SigHash.ANYONECANPAY.value; + + bos.write(0x00); + bos.write(sigHashType); + uint32ToByteStreamLE(this.version, bos); + uint32ToByteStreamLE(this.locktime, bos); + + if(!anyoneCanPay) { + ByteArrayOutputStream outpoints = new ByteArrayOutputStream(); + ByteArrayOutputStream outputValues = new ByteArrayOutputStream(); + ByteArrayOutputStream outputScriptPubKeys = new ByteArrayOutputStream(); + ByteArrayOutputStream inputSequences = new ByteArrayOutputStream(); + for(int i = 0; i < getInputs().size(); i++) { + TransactionInput input = getInputs().get(i); + input.getOutpoint().bitcoinSerializeToStream(outpoints); + Utils.uint64ToByteStreamLE(BigInteger.valueOf(spentUtxos.get(i).getValue()), outputValues); + byteArraySerialize(spentUtxos.get(i).getScriptBytes(), outputScriptPubKeys); + Utils.uint32ToByteStreamLE(input.getSequenceNumber(), inputSequences); + } + bos.write(Sha256Hash.hash(outpoints.toByteArray())); + bos.write(Sha256Hash.hash(outputValues.toByteArray())); + bos.write(Sha256Hash.hash(outputScriptPubKeys.toByteArray())); + bos.write(Sha256Hash.hash(inputSequences.toByteArray())); + } + + if(outType == SigHash.ALL.value) { + ByteArrayOutputStream outputs = new ByteArrayOutputStream(); + for(TransactionOutput output : getOutputs()) { + output.bitcoinSerializeToStream(outputs); + } + bos.write(Sha256Hash.hash(outputs.toByteArray())); + } + + byte spendType = 0x00; + if(annex != null) { + spendType |= 0x01; + } + if(scriptPath) { + spendType |= 0x02; + } + bos.write(spendType); + + if(anyoneCanPay) { + getInputs().get(inputIndex).getOutpoint().bitcoinSerializeToStream(bos); + Utils.uint32ToByteStreamLE(spentUtxos.get(inputIndex).getValue(), bos); + byteArraySerialize(spentUtxos.get(inputIndex).getScriptBytes(), bos); + Utils.uint32ToByteStreamLE(getInputs().get(inputIndex).getSequenceNumber(), bos); + } else { + Utils.uint32ToByteStreamLE(inputIndex, bos); + } + + if((spendType & 0x01) != 0) { + ByteArrayOutputStream annexStream = new ByteArrayOutputStream(); + byteArraySerialize(annex, annexStream); + bos.write(Sha256Hash.hash(annexStream.toByteArray())); + } + + if(outType == SigHash.SINGLE.value) { + if(inputIndex < getOutputs().size()) { + bos.write(Sha256Hash.hash(getOutputs().get(inputIndex).bitcoinSerialize())); + } else { + bos.write(Sha256Hash.ZERO_HASH.getBytes()); + } + } + + if(scriptPath) { + ByteArrayOutputStream leafStream = new ByteArrayOutputStream(); + leafStream.write(LEAF_VERSION_TAPSCRIPT); + byteArraySerialize(script.getProgram(), leafStream); + bos.write(Utils.taggedHash("TapLeaf", leafStream.toByteArray())); + bos.write(0x00); + Utils.uint32ToByteStreamLE(-1, bos); + } + + byte[] msgBytes = bos.toByteArray(); + long requiredLength = 175 - (anyoneCanPay ? 49 : 0) - (outType != SigHash.ALL.value && outType != SigHash.SINGLE.value ? 32 : 0) + (annex != null ? 32 : 0) + (scriptPath ? 37 : 0); + if(msgBytes.length != requiredLength) { + throw new IllegalStateException("Invalid message length, was " + msgBytes.length + " not " + requiredLength); + } + + return Sha256Hash.wrap(Utils.taggedHash("TapSighash", msgBytes)); + } catch (IOException e) { + throw new RuntimeException(e); // Cannot happen. + } + } + + private void byteArraySerialize(byte[] bytes, OutputStream outputStream) throws IOException { + outputStream.write(new VarInt(bytes.length).encode()); + outputStream.write(bytes); + } } diff --git a/src/main/java/com/sparrowwallet/drongo/protocol/TransactionSignature.java b/src/main/java/com/sparrowwallet/drongo/protocol/TransactionSignature.java index 3e9fb1f..0ac8613 100644 --- a/src/main/java/com/sparrowwallet/drongo/protocol/TransactionSignature.java +++ b/src/main/java/com/sparrowwallet/drongo/protocol/TransactionSignature.java @@ -24,7 +24,7 @@ public class TransactionSignature { /** Constructs a signature with the given components of the given type and SIGHASH_ALL. */ public TransactionSignature(BigInteger r, BigInteger s, Type type) { - this(r, s, type, SigHash.ALL.value); + this(r, s, type, type == Type.ECDSA ? SigHash.ALL.value : SigHash.ALL_TAPROOT.value); } /** Constructs a transaction signature based on the ECDSA signature. */ @@ -59,7 +59,7 @@ public class TransactionSignature { return (sighashFlags & SigHash.ANYONECANPAY.value) != 0; } - public SigHash getSigHash() { + private SigHash getSigHash() { boolean anyoneCanPay = anyoneCanPay(); final int mode = sighashFlags & 0x1f; if (mode == SigHash.NONE.value) { @@ -86,7 +86,7 @@ public class TransactionSignature { throw new RuntimeException(e); // Cannot happen. } } else if(schnorrSignature != null) { - SigHash sigHash = getSigHash(); + SigHash sigHash = getSigHash(); //Note this will return Sighash.ALL for Sighash.ALL_TAPROOT as well ByteBuffer buffer = ByteBuffer.allocate(sigHash == SigHash.ALL ? 64 : 65); buffer.put(schnorrSignature.encode()); if(sigHash != SigHash.ALL) { diff --git a/src/main/java/com/sparrowwallet/drongo/protocol/TransactionWitness.java b/src/main/java/com/sparrowwallet/drongo/protocol/TransactionWitness.java index 34be7d6..f5cad4d 100644 --- a/src/main/java/com/sparrowwallet/drongo/protocol/TransactionWitness.java +++ b/src/main/java/com/sparrowwallet/drongo/protocol/TransactionWitness.java @@ -14,6 +14,12 @@ import java.util.List; public class TransactionWitness extends ChildMessage { private List pushes; + public TransactionWitness(Transaction transaction, TransactionSignature signature) { + setParent(transaction); + this.pushes = new ArrayList<>(); + pushes.add(signature.encodeToBitcoin()); + } + public TransactionWitness(Transaction transaction, ECKey pubKey, TransactionSignature signature) { setParent(transaction); this.pushes = new ArrayList<>(); diff --git a/src/main/java/com/sparrowwallet/drongo/psbt/PSBT.java b/src/main/java/com/sparrowwallet/drongo/psbt/PSBT.java index 3e15391..ac69162 100644 --- a/src/main/java/com/sparrowwallet/drongo/psbt/PSBT.java +++ b/src/main/java/com/sparrowwallet/drongo/psbt/PSBT.java @@ -52,7 +52,7 @@ public class PSBT { this.transaction = transaction; for(int i = 0; i < transaction.getInputs().size(); i++) { - psbtInputs.add(new PSBTInput(transaction, i)); + psbtInputs.add(new PSBTInput(this, transaction, i)); } for(int i = 0; i < transaction.getOutputs().size(); i++) { @@ -111,12 +111,18 @@ public class PSBT { } Map derivedPublicKeys = new LinkedHashMap<>(); + ECKey tapInternalKey = null; for(Keystore keystore : wallet.getKeystores()) { WalletNode walletNode = utxoEntry.getValue(); - derivedPublicKeys.put(keystore.getPubKey(walletNode), keystore.getKeyDerivation().extend(walletNode.getDerivation())); + derivedPublicKeys.put(wallet.getScriptType().getOutputKey(keystore.getPubKey(walletNode)), keystore.getKeyDerivation().extend(walletNode.getDerivation())); + + //TODO: Implement Musig for multisig wallets + if(wallet.getScriptType() == ScriptType.P2TR) { + tapInternalKey = keystore.getPubKey(walletNode); + } } - PSBTInput psbtInput = new PSBTInput(wallet.getScriptType(), transaction, inputIndex, utxo, utxoIndex, redeemScript, witnessScript, derivedPublicKeys, Collections.emptyMap(), alwaysIncludeWitnessUtxo); + PSBTInput psbtInput = new PSBTInput(this, wallet.getScriptType(), transaction, inputIndex, utxo, utxoIndex, redeemScript, witnessScript, derivedPublicKeys, Collections.emptyMap(), tapInternalKey, alwaysIncludeWitnessUtxo); psbtInputs.add(psbtInput); } @@ -327,7 +333,7 @@ public class PSBT { } int inputIndex = this.psbtInputs.size(); - PSBTInput input = new PSBTInput(inputEntries, transaction, inputIndex); + PSBTInput input = new PSBTInput(this, inputEntries, transaction, inputIndex); if(verifySignatures) { boolean verified = input.verifySignatures(); @@ -400,7 +406,7 @@ public class PSBT { public boolean hasSignatures() { for(PSBTInput psbtInput : getPsbtInputs()) { - if(!psbtInput.getPartialSignatures().isEmpty() || psbtInput.getFinalScriptSig() != null || psbtInput.getFinalScriptWitness() != null) { + if(!psbtInput.getPartialSignatures().isEmpty() || psbtInput.getTapKeyPathSignature() != null || psbtInput.getFinalScriptSig() != null || psbtInput.getFinalScriptWitness() != null) { return true; } } diff --git a/src/main/java/com/sparrowwallet/drongo/psbt/PSBTInput.java b/src/main/java/com/sparrowwallet/drongo/psbt/PSBTInput.java index 6d6e1cb..3421912 100644 --- a/src/main/java/com/sparrowwallet/drongo/psbt/PSBTInput.java +++ b/src/main/java/com/sparrowwallet/drongo/psbt/PSBTInput.java @@ -4,12 +4,14 @@ import com.sparrowwallet.drongo.KeyDerivation; import com.sparrowwallet.drongo.Utils; import com.sparrowwallet.drongo.crypto.ECDSASignature; import com.sparrowwallet.drongo.crypto.ECKey; +import com.sparrowwallet.drongo.crypto.SchnorrSignature; import com.sparrowwallet.drongo.protocol.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.nio.charset.StandardCharsets; import java.util.*; +import java.util.stream.Collectors; import static com.sparrowwallet.drongo.protocol.ScriptType.*; import static com.sparrowwallet.drongo.psbt.PSBTEntry.*; @@ -26,7 +28,10 @@ public class PSBTInput { public static final byte PSBT_IN_FINAL_SCRIPTWITNESS = 0x08; public static final byte PSBT_IN_POR_COMMITMENT = 0x09; public static final byte PSBT_IN_PROPRIETARY = (byte)0xfc; + public static final byte PSBT_IN_TAP_KEY_SIG = 0x13; + public static final byte PSBT_IN_TAP_INTERNAL_KEY = 0x17; + private final PSBT psbt; private Transaction nonWitnessUtxo; private TransactionOutput witnessUtxo; private final Map partialSignatures = new LinkedHashMap<>(); @@ -38,20 +43,22 @@ public class PSBTInput { private TransactionWitness finalScriptWitness; private String porCommitment; private final Map proprietary = new LinkedHashMap<>(); + private TransactionSignature tapKeyPathSignature; + private ECKey tapInternalKey; private final Transaction transaction; private final int index; private static final Logger log = LoggerFactory.getLogger(PSBTInput.class); - PSBTInput(Transaction transaction, int index) { + PSBTInput(PSBT psbt, Transaction transaction, int index) { + this.psbt = psbt; this.transaction = transaction; this.index = index; } - PSBTInput(ScriptType scriptType, Transaction transaction, int index, Transaction utxo, int utxoIndex, Script redeemScript, Script witnessScript, Map derivedPublicKeys, Map proprietary, boolean alwaysAddNonWitnessTx) { - this(transaction, index); - sigHash = SigHash.ALL; + PSBTInput(PSBT psbt, ScriptType scriptType, Transaction transaction, int index, Transaction utxo, int utxoIndex, Script redeemScript, Script witnessScript, Map derivedPublicKeys, Map proprietary, ECKey tapInternalKey, boolean alwaysAddNonWitnessTx) { + this(psbt, transaction, index); if(Arrays.asList(ScriptType.WITNESS_TYPES).contains(scriptType)) { this.witnessUtxo = utxo.getOutputs().get(utxoIndex); @@ -69,9 +76,14 @@ public class PSBTInput { this.derivedPublicKeys.putAll(derivedPublicKeys); this.proprietary.putAll(proprietary); + + this.tapInternalKey = tapInternalKey; + + this.sigHash = getDefaultSigHash(); } - PSBTInput(List inputEntries, Transaction transaction, int index) throws PSBTParseException { + PSBTInput(PSBT psbt, List inputEntries, Transaction transaction, int index) throws PSBTParseException { + this.psbt = psbt; for(PSBTEntry entry : inputEntries) { switch(entry.getKeyType()) { case PSBT_IN_NON_WITNESS_UTXO: @@ -100,7 +112,7 @@ public class PSBTInput { case PSBT_IN_WITNESS_UTXO: entry.checkOneByteKey(); TransactionOutput witnessTxOutput = new TransactionOutput(null, entry.getData(), 0); - if(!P2SH.isScriptType(witnessTxOutput.getScript()) && !P2WPKH.isScriptType(witnessTxOutput.getScript()) && !P2WSH.isScriptType(witnessTxOutput.getScript())) { + if(!P2SH.isScriptType(witnessTxOutput.getScript()) && !P2WPKH.isScriptType(witnessTxOutput.getScript()) && !P2WSH.isScriptType(witnessTxOutput.getScript()) && !P2TR.isScriptType(witnessTxOutput.getScript())) { throw new PSBTParseException("Witness UTXO provided for non-witness or unknown input"); } this.witnessUtxo = witnessTxOutput; @@ -197,6 +209,14 @@ public class PSBTInput { this.proprietary.put(Utils.bytesToHex(entry.getKeyData()), Utils.bytesToHex(entry.getData())); log.debug("Found proprietary input " + Utils.bytesToHex(entry.getKeyData()) + ": " + Utils.bytesToHex(entry.getData())); break; + case PSBT_IN_TAP_KEY_SIG: + this.tapKeyPathSignature = TransactionSignature.decodeFromBitcoin(TransactionSignature.Type.SCHNORR, entry.getData(), true); + log.debug("Found input taproot key path signature " + Utils.bytesToHex(entry.getData())); + break; + case PSBT_IN_TAP_INTERNAL_KEY: + this.tapInternalKey = ECKey.fromPublicOnly(entry.getData()); + log.debug("Found input taproot internal key " + Utils.bytesToHex(entry.getData())); + break; default: log.warn("PSBT input not recognized key type: " + entry.getKeyType()); } @@ -210,7 +230,8 @@ public class PSBTInput { List entries = new ArrayList<>(); if(nonWitnessUtxo != null) { - entries.add(populateEntry(PSBT_IN_NON_WITNESS_UTXO, null, nonWitnessUtxo.bitcoinSerialize())); + //Serialize all nonWitnessUtxo fields without witness data (pre-Segwit serialization) to reduce PSBT size + entries.add(populateEntry(PSBT_IN_NON_WITNESS_UTXO, null, nonWitnessUtxo.bitcoinSerialize(false))); } if(witnessUtxo != null) { @@ -255,6 +276,14 @@ public class PSBTInput { entries.add(populateEntry(PSBT_IN_PROPRIETARY, Utils.hexToBytes(entry.getKey()), Utils.hexToBytes(entry.getValue()))); } + if(tapKeyPathSignature != null) { + entries.add(populateEntry(PSBT_IN_TAP_KEY_SIG, null, tapKeyPathSignature.encodeToBitcoin())); + } + + if(tapInternalKey != null) { + entries.add(populateEntry(PSBT_IN_TAP_INTERNAL_KEY, null, tapInternalKey.getPubKeyXCoord())); + } + return entries; } @@ -288,6 +317,14 @@ public class PSBTInput { } proprietary.putAll(psbtInput.proprietary); + + if(psbtInput.tapKeyPathSignature != null) { + tapKeyPathSignature = psbtInput.tapKeyPathSignature; + } + + if(psbtInput.tapInternalKey != null) { + tapInternalKey = psbtInput.tapInternalKey; + } } public Transaction getNonWitnessUtxo() { @@ -384,8 +421,30 @@ public class PSBTInput { return proprietary; } + public TransactionSignature getTapKeyPathSignature() { + return tapKeyPathSignature; + } + + public void setTapKeyPathSignature(TransactionSignature tapKeyPathSignature) { + this.tapKeyPathSignature = tapKeyPathSignature; + } + + public ECKey getTapInternalKey() { + return tapInternalKey; + } + + public void setTapInternalKey(ECKey tapInternalKey) { + this.tapInternalKey = tapInternalKey; + } + + public boolean isTaproot() { + return getScriptType() == P2TR; + } + public boolean isSigned() { - if(!getPartialSignatures().isEmpty()) { + if(getTapKeyPathSignature() != null) { + return true; + } else if(!getPartialSignatures().isEmpty()) { try { //All partial sigs are already verified int reqSigs = getSigningScript().getNumRequiredSignatures(); @@ -404,29 +463,46 @@ public class PSBTInput { return getFinalScriptWitness().getSignatures(); } else if(getFinalScriptSig() != null) { return getFinalScriptSig().getSignatures(); + } else if(getTapKeyPathSignature() != null) { + return List.of(getTapKeyPathSignature()); } else { return getPartialSignatures().values(); } } + private SigHash getDefaultSigHash() { + if(isTaproot()) { + return SigHash.ALL_TAPROOT; + } + + return SigHash.ALL; + } + public boolean sign(ECKey privKey) { SigHash localSigHash = getSigHash(); if(localSigHash == null) { - //Assume SigHash.ALL - localSigHash = SigHash.ALL; + localSigHash = getDefaultSigHash(); } if(getNonWitnessUtxo() != null || getWitnessUtxo() != null) { Script signingScript = getSigningScript(); if(signingScript != null) { Sha256Hash hash = getHashForSignature(signingScript, localSigHash); - ECDSASignature ecdsaSignature = privKey.signEcdsa(hash); - TransactionSignature transactionSignature = new TransactionSignature(ecdsaSignature, localSigHash); - ECKey pubKey = ECKey.fromPublicOnly(privKey); - getPartialSignatures().put(pubKey, transactionSignature); + if(isTaproot()) { + SchnorrSignature schnorrSignature = privKey.signSchnorr(hash); + tapKeyPathSignature = new TransactionSignature(schnorrSignature, localSigHash); - return true; + return true; + } else { + ECDSASignature ecdsaSignature = privKey.signEcdsa(hash); + TransactionSignature transactionSignature = new TransactionSignature(ecdsaSignature, localSigHash); + + ECKey pubKey = ECKey.fromPublicOnly(privKey); + getPartialSignatures().put(pubKey, transactionSignature); + + return true; + } } } @@ -436,8 +512,7 @@ public class PSBTInput { boolean verifySignatures() throws PSBTSignatureException { SigHash localSigHash = getSigHash(); if(localSigHash == null) { - //Assume SigHash.ALL - localSigHash = SigHash.ALL; + localSigHash = getDefaultSigHash(); } if(getNonWitnessUtxo() != null || getWitnessUtxo() != null) { @@ -445,10 +520,17 @@ public class PSBTInput { if(signingScript != null) { Sha256Hash hash = getHashForSignature(signingScript, localSigHash); - for(ECKey sigPublicKey : getPartialSignatures().keySet()) { - TransactionSignature signature = getPartialSignature(sigPublicKey); - if(!sigPublicKey.verify(hash, signature)) { - throw new PSBTSignatureException("Partial signature does not verify against provided public key"); + if(isTaproot() && tapKeyPathSignature != null) { + ECKey outputKey = ScriptType.P2TR.getPublicKeyFromScript(getUtxo().getScript()); + if(!outputKey.verify(hash, tapKeyPathSignature)) { + throw new PSBTSignatureException("Tweaked internal key does not verify against provided taproot keypath signature"); + } + } else { + for(ECKey sigPublicKey : getPartialSignatures().keySet()) { + TransactionSignature signature = getPartialSignature(sigPublicKey); + if(!sigPublicKey.verify(hash, signature)) { + throw new PSBTSignatureException("Partial signature does not verify against provided public key"); + } } } @@ -467,7 +549,7 @@ public class PSBTInput { Map signingKeys = new LinkedHashMap<>(); if(signingScript != null) { - Sha256Hash hash = getHashForSignature(signingScript, getSigHash() == null ? SigHash.ALL : getSigHash()); + Sha256Hash hash = getHashForSignature(signingScript, getSigHash() == null ? getDefaultSigHash() : getSigHash()); for(ECKey sigPublicKey : availableKeys) { for(TransactionSignature signature : signatures) { @@ -531,6 +613,11 @@ public class PSBTInput { } } + if(P2TR.isScriptType(signingScript)) { + //For now, only support keypath spends and just return the ScriptPubKey + //In future return the script from PSBT_IN_TAP_LEAF_SCRIPT + } + return signingScript; } @@ -554,13 +641,17 @@ public class PSBTInput { witnessScript = null; porCommitment = null; proprietary.clear(); + tapKeyPathSignature = null; } private Sha256Hash getHashForSignature(Script connectedScript, SigHash localSigHash) { Sha256Hash hash; ScriptType scriptType = getScriptType(); - if(Arrays.asList(WITNESS_TYPES).contains(scriptType)) { + if(scriptType == ScriptType.P2TR) { + List spentUtxos = psbt.getPsbtInputs().stream().map(PSBTInput::getUtxo).collect(Collectors.toList()); + hash = transaction.hashForTaprootSignature(spentUtxos, index, !P2TR.isScriptType(connectedScript), connectedScript, localSigHash, null); + } else if(Arrays.asList(WITNESS_TYPES).contains(scriptType)) { long prevValue = getUtxo().getValue(); hash = transaction.hashForWitnessSignature(index, connectedScript, prevValue, localSigHash); } else { diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java index 4dbb451..fb68f38 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java @@ -795,7 +795,7 @@ public class Wallet extends Persistable { for(TransactionInput txInput : signingNodes.keySet()) { WalletNode walletNode = signingNodes.get(txInput); - Map keystoreKeysForNode = getKeystores().stream().collect(Collectors.toMap(keystore -> keystore.getPubKey(walletNode), Function.identity(), + Map keystoreKeysForNode = getKeystores().stream().collect(Collectors.toMap(keystore -> getScriptType().getOutputKey(keystore.getPubKey(walletNode)), Function.identity(), (u, v) -> { throw new IllegalStateException("Duplicate keys from different keystores for node " + walletNode.getDerivationPath()); }, LinkedHashMap::new)); @@ -806,7 +806,15 @@ public class Wallet extends Persistable { TransactionOutput spentTxo = blockTransaction.getTransaction().getOutputs().get((int)txInput.getOutpoint().getIndex()); Script signingScript = getSigningScript(txInput, spentTxo); - Sha256Hash hash = txInput.hasWitness() ? transaction.hashForWitnessSignature(txInput.getIndex(), signingScript, spentTxo.getValue(), SigHash.ALL) : transaction.hashForLegacySignature(txInput.getIndex(), signingScript, SigHash.ALL); + Sha256Hash hash; + if(getScriptType() == P2TR) { + List spentOutputs = transaction.getInputs().stream().map(input -> transactions.get(input.getOutpoint().getHash()).getTransaction().getOutputs().get((int)input.getOutpoint().getIndex())).collect(Collectors.toList()); + hash = transaction.hashForTaprootSignature(spentOutputs, txInput.getIndex(), !P2TR.isScriptType(signingScript), signingScript, SigHash.ALL_TAPROOT, null); + } else if(txInput.hasWitness()) { + hash = transaction.hashForWitnessSignature(txInput.getIndex(), signingScript, spentTxo.getValue(), SigHash.ALL); + } else { + hash = transaction.hashForLegacySignature(txInput.getIndex(), signingScript, SigHash.ALL); + } for(ECKey sigPublicKey : keystoreKeysForNode.keySet()) { for(TransactionSignature signature : txInput.hasWitness() ? txInput.getWitness().getSignatures() : txInput.getScriptSig().getSignatures()) { @@ -887,12 +895,12 @@ public class Wallet extends Persistable { for(PSBTInput psbtInput : signingNodes.keySet()) { WalletNode walletNode = signingNodes.get(psbtInput); - Map keystoreKeysForNode = getKeystores().stream().collect(Collectors.toMap(keystore -> keystore.getPubKey(walletNode), Function.identity(), + Map keystoreKeysForNode = getKeystores().stream().collect(Collectors.toMap(keystore -> getScriptType().getOutputKey(keystore.getPubKey(walletNode)), Function.identity(), (u, v) -> { throw new IllegalStateException("Duplicate keys from different keystores for node " + walletNode.getDerivationPath()); }, LinkedHashMap::new)); Map keySignatureMap; - if(psbt.isFinalized()) { + if(psbt.isFinalized() || psbtInput.isTaproot()) { keySignatureMap = psbtInput.getSigningKeys(keystoreKeysForNode.keySet()); } else { keySignatureMap = psbtInput.getPartialSignatures(); @@ -916,7 +924,7 @@ public class Wallet extends Persistable { for(Keystore keystore : getKeystores()) { if(keystore.hasPrivateKey()) { for(Map.Entry signingEntry : signingNodes.entrySet()) { - ECKey privKey = keystore.getKey(signingEntry.getValue()); + ECKey privKey = getScriptType().getOutputKey(keystore.getKey(signingEntry.getValue())); PSBTInput psbtInput = signingEntry.getKey(); if(!psbtInput.isSigned()) { @@ -954,13 +962,15 @@ public class Wallet extends Persistable { } }; - if(psbtInput.getPartialSignatures().size() >= threshold && signingNode != null) { + //TODO: Handle taproot scriptpath spending + int signaturesAvailable = psbtInput.isTaproot() ? (psbtInput.getTapKeyPathSignature() != null ? 1 : 0) : psbtInput.getPartialSignatures().size(); + if(signaturesAvailable >= threshold && signingNode != null) { Transaction transaction = new Transaction(); TransactionInput finalizedTxInput; if(getPolicyType().equals(PolicyType.SINGLE)) { ECKey pubKey = getPubKey(signingNode); - TransactionSignature transactionSignature = psbtInput.getPartialSignature(pubKey); + TransactionSignature transactionSignature = psbtInput.isTaproot() ? psbtInput.getTapKeyPathSignature() : psbtInput.getPartialSignature(pubKey); if(transactionSignature == null) { throw new IllegalArgumentException("Pubkey of partial signature does not match wallet pubkey"); } diff --git a/src/test/java/com/sparrowwallet/drongo/protocol/TransactionTest.java b/src/test/java/com/sparrowwallet/drongo/protocol/TransactionTest.java index 3bce9ec..dcc266e 100644 --- a/src/test/java/com/sparrowwallet/drongo/protocol/TransactionTest.java +++ b/src/test/java/com/sparrowwallet/drongo/protocol/TransactionTest.java @@ -4,6 +4,7 @@ import com.sparrowwallet.drongo.Utils; import com.sparrowwallet.drongo.address.Address; import com.sparrowwallet.drongo.address.InvalidAddressException; import com.sparrowwallet.drongo.crypto.ECKey; +import com.sparrowwallet.drongo.crypto.SchnorrSignature; import org.junit.Assert; import org.junit.Test; @@ -479,4 +480,27 @@ public class TransactionTest { Assert.assertEquals(spendingHex, constructedHex); } + + @Test + public void signBip340() { + ECKey privKey = ECKey.fromPrivate(Utils.hexToBytes("0000000000000000000000000000000000000000000000000000000000000003")); + Assert.assertEquals("F9308A019258C31049344F85F89D5229B531C845836F99B08601F113BCE036F9", Utils.bytesToHex(privKey.getPubKeyXCoord()).toUpperCase()); + SchnorrSignature sig = privKey.signSchnorr(Sha256Hash.ZERO_HASH); + Assert.assertEquals("E907831F80848D1069A5371B402410364BDF1C5F8307B0084C55F1CE2DCA821525F66A4A85EA8B71E482A74F382D2CE5EBEEE8FDB2172F477DF4900D310536C0", Utils.bytesToHex(sig.encode()).toUpperCase()); + } + + @Test + public void signTaprootKeypath() { + Transaction tx = new Transaction(Utils.hexToBytes("02000000000101786ed355f998b98f8ef8ef2acf461577325cf170a9133d48a17aba957eb97ff00000000000ffffffff0100e1f50500000000220020693a94699e6e41ab302fd623a9bf5a5b2d6606cbfb35c550d1cb4300451356a102473044022004cc317c20eb9e372cb0e640f51eb2b8311616125321b11dbaa5671db5a3ca2a02207ae3d2771b565be98ae56e21045b9629c94b6ca8f4e3932260e54d4f0e2016b30121032da1692a41a61ad14f3795b31d33431abf8d6ee161b997d004c26a37bc20083500000000")); + Transaction spendingTx = new Transaction(Utils.hexToBytes("01000000011af4dca4a6bc6da092edca5390355891da9bbe76d2be1c04d067ec9c3a3d22b10000000000000000000180f0fa0200000000160014a3bcb5f272025cc66dc42e7518a5846bd60a9c9600000000")); + + Sha256Hash hash = spendingTx.hashForTaprootSignature(tx.getOutputs(), 0, false, null, SigHash.ALL_TAPROOT, null); + ECKey privateKey = ECKey.fromPrivate(Utils.hexToBytes("d9bc817b92916a24b87d25dc48ef466b4fcd6c89cf90afbc17cba40eb8b91330")); + SchnorrSignature sig = privateKey.signSchnorr(hash); + + Assert.assertEquals("7b04f59bc8f5c2c33c9b8acbf94743de74cc25a6052b52ff61a516f7c5ca19cc68345ba99b354f22bfaf5c04de395b9223f3bf0a5c351fc1cc68c224f4e5b202", Utils.bytesToHex(sig.encode())); + + ECKey pubKey = ECKey.fromPublicOnly(privateKey); + Assert.assertTrue(pubKey.verify(hash, new TransactionSignature(sig, SigHash.ALL_TAPROOT))); + } } From db081695e84f38a184567b00cad1af0f0e7e1b67 Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Thu, 15 Jul 2021 11:08:59 +0200 Subject: [PATCH 049/155] fix p2tr script required sigs --- src/main/java/com/sparrowwallet/drongo/protocol/Script.java | 3 ++- src/main/java/com/sparrowwallet/drongo/wallet/WalletModel.java | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/sparrowwallet/drongo/protocol/Script.java b/src/main/java/com/sparrowwallet/drongo/protocol/Script.java index 3dd051f..11aa82e 100644 --- a/src/main/java/com/sparrowwallet/drongo/protocol/Script.java +++ b/src/main/java/com/sparrowwallet/drongo/protocol/Script.java @@ -200,7 +200,8 @@ public class Script { } public int getNumRequiredSignatures() throws NonStandardScriptException { - if(P2PK.isScriptType(this) || P2PKH.isScriptType(this) || P2WPKH.isScriptType(this)) { + //TODO: Handle P2TR script path spends + if(P2PK.isScriptType(this) || P2PKH.isScriptType(this) || P2WPKH.isScriptType(this) || P2TR.isScriptType(this)) { return 1; } diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/WalletModel.java b/src/main/java/com/sparrowwallet/drongo/wallet/WalletModel.java index 708ec92..29efd53 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/WalletModel.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/WalletModel.java @@ -1,7 +1,7 @@ package com.sparrowwallet.drongo.wallet; public enum WalletModel { - SEED, SPARROW, BITCOIN_CORE, ELECTRUM, TREZOR_1, TREZOR_T, COLDCARD, LEDGER_NANO_S, LEDGER_NANO_X, DIGITALBITBOX_01, KEEPKEY, SPECTER_DESKTOP, COBO_VAULT, BITBOX_02, SPECTER_DIY, PASSPORT, BLUE_WALLET, KEYSTONE, SEEDSIGNER; + SEED, SPARROW, BITCOIN_CORE, ELECTRUM, TREZOR_1, TREZOR_T, COLDCARD, LEDGER_NANO_S, LEDGER_NANO_X, DIGITALBITBOX_01, KEEPKEY, SPECTER_DESKTOP, COBO_VAULT, BITBOX_02, SPECTER_DIY, PASSPORT, BLUE_WALLET, KEYSTONE, SEEDSIGNER, CARAVAN; public static WalletModel getModel(String model) { return valueOf(model.toUpperCase()); From 46e4413cf6ed052d3377550760c9ffcf64a0c68d Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Mon, 19 Jul 2021 12:34:58 +0200 Subject: [PATCH 050/155] activate p2tr script type on testnet, and on mainnet after activation --- .../java/com/sparrowwallet/drongo/protocol/ScriptType.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/sparrowwallet/drongo/protocol/ScriptType.java b/src/main/java/com/sparrowwallet/drongo/protocol/ScriptType.java index 3d8da30..cc4260d 100644 --- a/src/main/java/com/sparrowwallet/drongo/protocol/ScriptType.java +++ b/src/main/java/com/sparrowwallet/drongo/protocol/ScriptType.java @@ -8,6 +8,8 @@ import com.sparrowwallet.drongo.crypto.ChildNumber; import com.sparrowwallet.drongo.crypto.ECKey; import com.sparrowwallet.drongo.policy.PolicyType; +import java.time.LocalDate; +import java.time.Month; import java.util.*; import java.util.stream.Collectors; @@ -1132,10 +1134,13 @@ public enum ScriptType { @Override public List getAllowedPolicyTypes() { - return Network.get() == Network.REGTEST || Network.get() == Network.SIGNET ? List.of(SINGLE) : Collections.emptyList(); + return (Network.get() == Network.MAINNET && LocalDate.now().isAfter(TAPROOT_MAINNET_ACTIVATION_DATE)) || Network.get() == Network.TESTNET || Network.get() == Network.REGTEST || Network.get() == Network.SIGNET ? List.of(SINGLE) : Collections.emptyList(); } }; + //To avoid relying on a network-dependent block height >= 709632 check, use a approximate activation date. This can be removed once Taproot has activated on mainnet. + private static final LocalDate TAPROOT_MAINNET_ACTIVATION_DATE = LocalDate.of(2021, Month.NOVEMBER, 22); + private final String name; private final String description; private final String defaultDerivationPath; From debafd42e8dd017779e193f609717a3eb72cd39a Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Fri, 30 Jul 2021 14:15:08 +0200 Subject: [PATCH 051/155] add wallet hierarchy-aware convenience naming methods --- .../sparrowwallet/drongo/wallet/Wallet.java | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java index fb68f38..406e320 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java @@ -61,6 +61,22 @@ public class Wallet extends Persistable { return name; } + public String getFullName() { + if(isMasterWallet()) { + return name; + } + + return getMasterWallet().getName() + "-" + name; + } + + public String getMasterName() { + if(isMasterWallet()) { + return name; + } + + return getMasterWallet().getName(); + } + public void setName(String name) { this.name = name; } @@ -1233,6 +1249,6 @@ public class Wallet extends Persistable { @Override public String toString() { - return getName(); + return getFullName(); } } From 8fd14ce1338328efb6cea4e847766515b5b217a0 Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Mon, 2 Aug 2021 16:10:06 +0200 Subject: [PATCH 052/155] fix psbt testcase --- src/main/java/com/sparrowwallet/drongo/psbt/PSBTInput.java | 2 +- src/test/java/com/sparrowwallet/drongo/psbt/PSBTTest.java | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/sparrowwallet/drongo/psbt/PSBTInput.java b/src/main/java/com/sparrowwallet/drongo/psbt/PSBTInput.java index 3421912..4d89317 100644 --- a/src/main/java/com/sparrowwallet/drongo/psbt/PSBTInput.java +++ b/src/main/java/com/sparrowwallet/drongo/psbt/PSBTInput.java @@ -438,7 +438,7 @@ public class PSBTInput { } public boolean isTaproot() { - return getScriptType() == P2TR; + return getUtxo() != null && getScriptType() == P2TR; } public boolean isSigned() { diff --git a/src/test/java/com/sparrowwallet/drongo/psbt/PSBTTest.java b/src/test/java/com/sparrowwallet/drongo/psbt/PSBTTest.java index 1d41e8b..930f7b3 100644 --- a/src/test/java/com/sparrowwallet/drongo/psbt/PSBTTest.java +++ b/src/test/java/com/sparrowwallet/drongo/psbt/PSBTTest.java @@ -312,7 +312,8 @@ public class PSBTTest { String psbtStr4 = "cHNidP8BAHUCAAAAASaBcTce3/KF6Tet7qSze3gADAVmy7OtZGQXE8pCFxv2AAAAAAD+////AtPf9QUAAAAAGXapFNDFmQPFusKGh2DpD9UhpGZap2UgiKwA4fUFAAAAABepFDVF5uM7gyxHBQ8k0+65PJwDlIvHh7MuEwAAAQD9pQEBAAAAAAECiaPHHqtNIOA3G7ukzGmPopXJRjr6Ljl/hTPMti+VZ+UBAAAAFxYAFL4Y0VKpsBIDna89p95PUzSe7LmF/////4b4qkOnHf8USIk6UwpyN+9rRgi7st0tAXHmOuxqSJC0AQAAABcWABT+Pp7xp0XpdNkCxDVZQ6vLNL1TU/////8CAMLrCwAAAAAZdqkUhc/xCX/Z4Ai7NK9wnGIZeziXikiIrHL++E4sAAAAF6kUM5cluiHv1irHU6m80GfWx6ajnQWHAkcwRAIgJxK+IuAnDzlPVoMR3HyppolwuAJf3TskAinwf4pfOiQCIAGLONfc0xTnNMkna9b7QPZzMlvEuqFEyADS8vAtsnZcASED0uFWdJQbrUqZY3LLh+GFbTZSYG2YVi/jnF6efkE/IQUCSDBFAiEA0SuFLYXc2WHS9fSrZgZU327tzHlMDDPOXMMJ/7X85Y0CIGczio4OFyXBl/saiK9Z9R5E5CVbIBZ8hoQDHAXR8lkqASECI7cr7vCWXRC+B3jv7NYfysb3mk6haTkzgHNEZPhPKrMAAAAAAQMEAQAAAAAAAA=="; PSBT psbt4 = PSBT.fromString(psbtStr4); - Assert.assertEquals(psbtStr4, psbt4.toBase64String()); + String noWitnessDataPsbt = "cHNidP8BAHUCAAAAASaBcTce3/KF6Tet7qSze3gADAVmy7OtZGQXE8pCFxv2AAAAAAD+////AtPf9QUAAAAAGXapFNDFmQPFusKGh2DpD9UhpGZap2UgiKwA4fUFAAAAABepFDVF5uM7gyxHBQ8k0+65PJwDlIvHh7MuEwAAAQDMAQAAAAKJo8ceq00g4Dcbu6TMaY+ilclGOvouOX+FM8y2L5Vn5QEAAAAXFgAUvhjRUqmwEgOdrz2n3k9TNJ7suYX/////hviqQ6cd/xRIiTpTCnI372tGCLuy3S0BceY67GpIkLQBAAAAFxYAFP4+nvGnRel02QLENVlDq8s0vVNT/////wIAwusLAAAAABl2qRSFz/EJf9ngCLs0r3CcYhl7OJeKSIiscv74TiwAAAAXqRQzlyW6Ie/WKsdTqbzQZ9bHpqOdBYcAAAAAAQMEAQAAAAAAAA=="; + Assert.assertEquals(noWitnessDataPsbt, psbt4.toBase64String()); } @Test From eab42c0f0580452968f579bba3904bfc6480ae0f Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Thu, 12 Aug 2021 17:48:36 +0200 Subject: [PATCH 053/155] support for standardized child wallet accounts --- .../sparrowwallet/drongo/wallet/Payment.java | 13 +++ .../drongo/wallet/StandardAccount.java | 48 ++++++++++ .../sparrowwallet/drongo/wallet/Wallet.java | 88 +++++++++++++++++++ .../drongo/wallet/WalletTransaction.java | 16 +++- 4 files changed, 163 insertions(+), 2 deletions(-) create mode 100644 src/main/java/com/sparrowwallet/drongo/wallet/StandardAccount.java diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/Payment.java b/src/main/java/com/sparrowwallet/drongo/wallet/Payment.java index ce3998b..18f2d99 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/Payment.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/Payment.java @@ -7,6 +7,7 @@ public class Payment { private String label; private long amount; private boolean sendMax; + private Type type = Type.DEFAULT; public Payment(Address address, String label, long amount, boolean sendMax) { this.address = address; @@ -46,4 +47,16 @@ public class Payment { public void setSendMax(boolean sendMax) { this.sendMax = sendMax; } + + public Type getType() { + return type; + } + + public void setType(Type type) { + this.type = type; + } + + public enum Type { + DEFAULT, WHIRLPOOL_FEE; + } } diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/StandardAccount.java b/src/main/java/com/sparrowwallet/drongo/wallet/StandardAccount.java new file mode 100644 index 0000000..b6778b7 --- /dev/null +++ b/src/main/java/com/sparrowwallet/drongo/wallet/StandardAccount.java @@ -0,0 +1,48 @@ +package com.sparrowwallet.drongo.wallet; + +import com.sparrowwallet.drongo.crypto.ChildNumber; + +import java.util.List; + +public enum StandardAccount { + ACCOUNT_0("Account #0", new ChildNumber(0, true)), + ACCOUNT_1("Account #1", new ChildNumber(1, true)), + ACCOUNT_2("Account #2", new ChildNumber(2, true)), + ACCOUNT_3("Account #3", new ChildNumber(3, true)), + ACCOUNT_4("Account #4", new ChildNumber(4, true)), + ACCOUNT_5("Account #5", new ChildNumber(5, true)), + ACCOUNT_6("Account #6", new ChildNumber(6, true)), + ACCOUNT_7("Account #7", new ChildNumber(7, true)), + ACCOUNT_8("Account #8", new ChildNumber(8, true)), + ACCOUNT_9("Account #9", new ChildNumber(9, true)), + WHIRLPOOL_PREMIX("Premix", new ChildNumber(2147483645, true)), + WHIRLPOOL_POSTMIX("Postmix", new ChildNumber(2147483646, true)), + WHIRLPOOL_BADBANK("Badbank", new ChildNumber(2147483644, true)); + + public static final List WHIRLPOOL_ACCOUNTS = List.of(WHIRLPOOL_PREMIX, WHIRLPOOL_POSTMIX, WHIRLPOOL_BADBANK); + + StandardAccount(String name, ChildNumber childNumber) { + this.name = name; + this.childNumber = childNumber; + } + + private final String name; + private final ChildNumber childNumber; + + public String getName() { + return name; + } + + public ChildNumber getChildNumber() { + return childNumber; + } + + public int getAccountNumber() { + return childNumber.num(); + } + + @Override + public String toString() { + return name; + } +} diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java index 406e320..1f6abf5 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java @@ -1,9 +1,11 @@ package com.sparrowwallet.drongo.wallet; import com.sparrowwallet.drongo.BitcoinUnit; +import com.sparrowwallet.drongo.KeyDerivation; import com.sparrowwallet.drongo.KeyPurpose; import com.sparrowwallet.drongo.Network; import com.sparrowwallet.drongo.address.Address; +import com.sparrowwallet.drongo.crypto.ChildNumber; import com.sparrowwallet.drongo.crypto.ECKey; import com.sparrowwallet.drongo.crypto.Key; import com.sparrowwallet.drongo.policy.Policy; @@ -77,6 +79,92 @@ public class Wallet extends Persistable { return getMasterWallet().getName(); } + public Wallet addChildWallet(StandardAccount standardAccount) { + Wallet childWallet = this.copy(); + + if(!isMasterWallet()) { + throw new IllegalStateException("Cannot add child wallet to existing child wallet"); + } + + if(!childWallet.containsPrivateKeys()) { + throw new IllegalStateException("Cannot derive child wallet xpub without private keys"); + } + + if(childWallet.isEncrypted()) { + throw new IllegalStateException("Cannot derive child wallet xpub from encrypted wallet"); + } + + childWallet.setId(null); + childWallet.setName(standardAccount.getName()); + childWallet.purposeNodes.clear(); + childWallet.transactions.clear(); + childWallet.storedBlockHeight = null; + childWallet.gapLimit = null; + childWallet.birthDate = null; + + for(Keystore keystore : childWallet.getKeystores()) { + KeyDerivation keyDerivation = keystore.getKeyDerivation(); + List childDerivation = new ArrayList<>(keyDerivation.getDerivation().subList(0, keyDerivation.getDerivation().size() - 1)); + childDerivation.add(standardAccount.getChildNumber()); + + try { + Keystore derivedKeystore = Keystore.fromSeed(keystore.getSeed(), childDerivation); + keystore.setKeyDerivation(derivedKeystore.getKeyDerivation()); + keystore.setExtendedPublicKey(derivedKeystore.getExtendedPublicKey()); + keystore.getSeed().setPassphrase(keystore.getSeed().getPassphrase()); + } catch(Exception e) { + throw new IllegalStateException("Cannot derive keystore for " + standardAccount + " account", e); + } + } + + childWallet.setMasterWallet(this); + getChildWallets().add(childWallet); + return childWallet; + } + + public Wallet getChildWallet(StandardAccount account) { + for(Wallet childWallet : getChildWallets()) { + for(Keystore keystore : childWallet.getKeystores()) { + if(keystore.getKeyDerivation().getDerivation().get(keystore.getKeyDerivation().getDerivation().size() - 1).equals(account.getChildNumber())) { + return childWallet; + } + } + } + + return null; + } + + public StandardAccount getStandardAccountType() { + int accountIndex = getAccountIndex(); + return Arrays.stream(StandardAccount.values()).filter(standardAccount -> standardAccount.getChildNumber().num() == accountIndex).findFirst().orElse(null); + } + + public int getAccountIndex() { + int index = -1; + + for(Keystore keystore : getKeystores()) { + int keystoreAccount = getScriptType().getAccount(keystore.getKeyDerivation().getDerivationPath()); + if(keystoreAccount != -1 && (index == -1 || keystoreAccount == index)) { + index = keystoreAccount; + } + } + + return index; + } + + public boolean isWhirlpoolMasterWallet() { + if(!isMasterWallet()) { + return false; + } + + Set whirlpoolAccounts = new HashSet<>(Set.of(StandardAccount.WHIRLPOOL_PREMIX, StandardAccount.WHIRLPOOL_POSTMIX, StandardAccount.WHIRLPOOL_BADBANK)); + for(Wallet childWallet : getChildWallets()) { + whirlpoolAccounts.remove(childWallet.getStandardAccountType()); + } + + return whirlpoolAccounts.isEmpty(); + } + public void setName(String name) { this.name = name; } diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/WalletTransaction.java b/src/main/java/com/sparrowwallet/drongo/wallet/WalletTransaction.java index 8c5bce1..e6aa32e 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/WalletTransaction.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/WalletTransaction.java @@ -98,8 +98,20 @@ public class WalletTransaction { } public boolean isConsolidationSend(Payment payment) { - if(payment.getAddress() != null && getWallet() != null) { - return getWallet().isWalletOutputScript(payment.getAddress().getOutputScript()); + return isWalletSend(getWallet(), payment); + } + + public boolean isPremixSend(Payment payment) { + return isWalletSend(getWallet().getChildWallet(StandardAccount.WHIRLPOOL_PREMIX), payment); + } + + public boolean isBadbankSend(Payment payment) { + return isWalletSend(getWallet().getChildWallet(StandardAccount.WHIRLPOOL_BADBANK), payment); + } + + public boolean isWalletSend(Wallet wallet, Payment payment) { + if(payment.getAddress() != null && wallet != null) { + return wallet.isWalletOutputScript(payment.getAddress().getOutputScript()); } return false; From 2eedd2290cbe1dd559247f1ee934cece81fa7419 Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Mon, 16 Aug 2021 10:45:48 +0200 Subject: [PATCH 054/155] fix npe for new wallets --- src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java index 1f6abf5..d23ca26 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java @@ -143,9 +143,11 @@ public class Wallet extends Persistable { int index = -1; for(Keystore keystore : getKeystores()) { - int keystoreAccount = getScriptType().getAccount(keystore.getKeyDerivation().getDerivationPath()); - if(keystoreAccount != -1 && (index == -1 || keystoreAccount == index)) { - index = keystoreAccount; + if(keystore.getKeyDerivation() != null) { + int keystoreAccount = getScriptType().getAccount(keystore.getKeyDerivation().getDerivationPath()); + if(keystoreAccount != -1 && (index == -1 || keystoreAccount == index)) { + index = keystoreAccount; + } } } From 81c202198e8b057271414d15259df556a90bc6f1 Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Mon, 23 Aug 2021 16:34:40 +0200 Subject: [PATCH 055/155] add utxo mix data storage to wallet --- .../com/sparrowwallet/drongo/KeyPurpose.java | 4 +++ .../drongo/wallet/StandardAccount.java | 1 + .../drongo/wallet/UtxoMixData.java | 30 +++++++++++++++++++ .../sparrowwallet/drongo/wallet/Wallet.java | 14 +++++++++ .../drongo/wallet/WalletModel.java | 2 +- 5 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 src/main/java/com/sparrowwallet/drongo/wallet/UtxoMixData.java diff --git a/src/main/java/com/sparrowwallet/drongo/KeyPurpose.java b/src/main/java/com/sparrowwallet/drongo/KeyPurpose.java index 4563692..0af33fb 100644 --- a/src/main/java/com/sparrowwallet/drongo/KeyPurpose.java +++ b/src/main/java/com/sparrowwallet/drongo/KeyPurpose.java @@ -2,9 +2,13 @@ package com.sparrowwallet.drongo; import com.sparrowwallet.drongo.crypto.ChildNumber; +import java.util.List; + public enum KeyPurpose { RECEIVE(ChildNumber.ZERO), CHANGE(ChildNumber.ONE); + public static final List DEFAULT_PURPOSES = List.of(RECEIVE, CHANGE); + private final ChildNumber pathIndex; KeyPurpose(ChildNumber pathIndex) { diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/StandardAccount.java b/src/main/java/com/sparrowwallet/drongo/wallet/StandardAccount.java index b6778b7..4d66905 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/StandardAccount.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/StandardAccount.java @@ -20,6 +20,7 @@ public enum StandardAccount { WHIRLPOOL_BADBANK("Badbank", new ChildNumber(2147483644, true)); public static final List WHIRLPOOL_ACCOUNTS = List.of(WHIRLPOOL_PREMIX, WHIRLPOOL_POSTMIX, WHIRLPOOL_BADBANK); + public static final List WHIRLPOOL_MIX_ACCOUNTS = List.of(WHIRLPOOL_PREMIX, WHIRLPOOL_POSTMIX); StandardAccount(String name, ChildNumber childNumber) { this.name = name; diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/UtxoMixData.java b/src/main/java/com/sparrowwallet/drongo/wallet/UtxoMixData.java new file mode 100644 index 0000000..07eaf10 --- /dev/null +++ b/src/main/java/com/sparrowwallet/drongo/wallet/UtxoMixData.java @@ -0,0 +1,30 @@ +package com.sparrowwallet.drongo.wallet; + +public class UtxoMixData extends Persistable { + private final String poolId; + private final int mixesDone; + private final Long forwarding; + + public UtxoMixData(String poolId, int mixesDone, Long forwarding) { + this.poolId = poolId; + this.mixesDone = mixesDone; + this.forwarding = forwarding; + } + + public String getPoolId() { + return poolId; + } + + public int getMixesDone() { + return mixesDone; + } + + public Long getForwarding() { + return forwarding; + } + + @Override + public String toString() { + return "{poolId:" + poolId + ", mixesDone:" + mixesDone + ", forwarding:" + forwarding + "}"; + } +} diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java index d23ca26..aaf1078 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java @@ -14,6 +14,7 @@ import com.sparrowwallet.drongo.protocol.*; import com.sparrowwallet.drongo.psbt.PSBT; import com.sparrowwallet.drongo.psbt.PSBTInput; +import java.nio.charset.StandardCharsets; import java.util.*; import java.util.function.Function; import java.util.stream.Collectors; @@ -35,6 +36,7 @@ public class Wallet extends Persistable { private List keystores = new ArrayList<>(); private final TreeSet purposeNodes = new TreeSet<>(); private final Map transactions = new HashMap<>(); + private final Map utxoMixes = new HashMap<>(); private Integer storedBlockHeight; private Integer gapLimit; private Date birthDate; @@ -167,6 +169,10 @@ public class Wallet extends Persistable { return whirlpoolAccounts.isEmpty(); } + public boolean isWhirlpoolMixWallet() { + return !isMasterWallet() && StandardAccount.WHIRLPOOL_MIX_ACCOUNTS.contains(getStandardAccountType()); + } + public void setName(String name) { this.name = name; } @@ -224,6 +230,14 @@ public class Wallet extends Persistable { } } + public UtxoMixData getUtxoMixData(BlockTransactionHashIndex utxo) { + return utxoMixes.get(Sha256Hash.of(utxo.toString().getBytes(StandardCharsets.UTF_8))); + } + + public Map getUtxoMixes() { + return utxoMixes; + } + public Integer getStoredBlockHeight() { return storedBlockHeight; } diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/WalletModel.java b/src/main/java/com/sparrowwallet/drongo/wallet/WalletModel.java index 29efd53..afd24b1 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/WalletModel.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/WalletModel.java @@ -44,7 +44,7 @@ public enum WalletModel { } public boolean alwaysIncludeNonWitnessUtxo() { - if(this == COLDCARD || this == COBO_VAULT || this == PASSPORT) { + if(this == COLDCARD || this == COBO_VAULT || this == PASSPORT || this == KEYSTONE) { return false; } From 0947ea10c81b3e4b8da82adab2410f33f0a77cd2 Mon Sep 17 00:00:00 2001 From: zeroleak Date: Fri, 27 Aug 2021 09:30:11 +0200 Subject: [PATCH 056/155] upgrade to whirlpool-client 0.23.30-early4 + extlibj 0.0.19-dsk3 --- .../drongo/wallet/UtxoMixData.java | 18 ++++++------------ .../sparrowwallet/drongo/wallet/Wallet.java | 6 +++++- 2 files changed, 11 insertions(+), 13 deletions(-) diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/UtxoMixData.java b/src/main/java/com/sparrowwallet/drongo/wallet/UtxoMixData.java index 07eaf10..1bf8764 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/UtxoMixData.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/UtxoMixData.java @@ -1,30 +1,24 @@ package com.sparrowwallet.drongo.wallet; public class UtxoMixData extends Persistable { - private final String poolId; private final int mixesDone; - private final Long forwarding; + private final Long expired; - public UtxoMixData(String poolId, int mixesDone, Long forwarding) { - this.poolId = poolId; + public UtxoMixData(int mixesDone, Long expired) { this.mixesDone = mixesDone; - this.forwarding = forwarding; - } - - public String getPoolId() { - return poolId; + this.expired = expired; } public int getMixesDone() { return mixesDone; } - public Long getForwarding() { - return forwarding; + public Long getExpired() { + return expired; } @Override public String toString() { - return "{poolId:" + poolId + ", mixesDone:" + mixesDone + ", forwarding:" + forwarding + "}"; + return "{mixesDone:" + mixesDone + ", expired: " + expired + "}"; } } diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java index aaf1078..cd6d659 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java @@ -231,7 +231,11 @@ public class Wallet extends Persistable { } public UtxoMixData getUtxoMixData(BlockTransactionHashIndex utxo) { - return utxoMixes.get(Sha256Hash.of(utxo.toString().getBytes(StandardCharsets.UTF_8))); + return getUtxoMixData(Sha256Hash.of(utxo.toString().getBytes(StandardCharsets.UTF_8))); + } + + public UtxoMixData getUtxoMixData(Sha256Hash utxoKey) { + return utxoMixes.get(utxoKey); } public Map getUtxoMixes() { From 7ac4bce14f04163c57b94e34945b5e4a1bf79eb6 Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Fri, 27 Aug 2021 15:58:23 +0200 Subject: [PATCH 057/155] support multiple utxo sets and change outputs --- .../com/sparrowwallet/drongo/psbt/PSBT.java | 4 +- .../drongo/wallet/BnBUtxoSelector.java | 2 +- .../drongo/wallet/KnapsackUtxoSelector.java | 2 +- .../drongo/wallet/MaxUtxoSelector.java | 2 +- .../sparrowwallet/drongo/wallet/Payment.java | 2 +- .../drongo/wallet/PresetUtxoSelector.java | 2 +- .../drongo/wallet/PriorityUtxoSelector.java | 2 +- .../drongo/wallet/SingleSetUtxoSelector.java | 13 +++ .../drongo/wallet/StonewallUtxoSelector.java | 76 ++++++++++++++ .../drongo/wallet/UtxoSelector.java | 3 +- .../sparrowwallet/drongo/wallet/Wallet.java | 99 ++++++++++++++----- .../drongo/wallet/WalletTransaction.java | 23 ++--- 12 files changed, 180 insertions(+), 50 deletions(-) create mode 100644 src/main/java/com/sparrowwallet/drongo/wallet/SingleSetUtxoSelector.java create mode 100644 src/main/java/com/sparrowwallet/drongo/wallet/StonewallUtxoSelector.java diff --git a/src/main/java/com/sparrowwallet/drongo/psbt/PSBT.java b/src/main/java/com/sparrowwallet/drongo/psbt/PSBT.java index ac69162..e26caae 100644 --- a/src/main/java/com/sparrowwallet/drongo/psbt/PSBT.java +++ b/src/main/java/com/sparrowwallet/drongo/psbt/PSBT.java @@ -132,8 +132,8 @@ public class PSBT { Address address = txOutput.getScript().getToAddresses()[0]; if(walletTransaction.getPayments().stream().anyMatch(payment -> payment.getAddress().equals(address))) { outputNodes.add(wallet.getWalletAddresses().getOrDefault(address, null)); - } else if(address.equals(wallet.getAddress(walletTransaction.getChangeNode()))) { - outputNodes.add(walletTransaction.getChangeNode()); + } else if(walletTransaction.getChangeMap().keySet().stream().anyMatch(changeNode -> wallet.getAddress(changeNode).equals(address))) { + outputNodes.add(wallet.getWalletAddresses().getOrDefault(address, null)); } } catch(NonStandardScriptException e) { //Should never happen diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/BnBUtxoSelector.java b/src/main/java/com/sparrowwallet/drongo/wallet/BnBUtxoSelector.java index c3cacca..b3bcb47 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/BnBUtxoSelector.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/BnBUtxoSelector.java @@ -6,7 +6,7 @@ import org.slf4j.LoggerFactory; import java.util.*; -public class BnBUtxoSelector implements UtxoSelector { +public class BnBUtxoSelector extends SingleSetUtxoSelector { private static final Logger log = LoggerFactory.getLogger(BnBUtxoSelector.class); private static final int TOTAL_TRIES = 100000; diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/KnapsackUtxoSelector.java b/src/main/java/com/sparrowwallet/drongo/wallet/KnapsackUtxoSelector.java index 93c615f..5bc33b6 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/KnapsackUtxoSelector.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/KnapsackUtxoSelector.java @@ -5,7 +5,7 @@ import com.sparrowwallet.drongo.protocol.Transaction; import java.util.*; import java.util.stream.Collectors; -public class KnapsackUtxoSelector implements UtxoSelector { +public class KnapsackUtxoSelector extends SingleSetUtxoSelector { private static final long MIN_CHANGE = Transaction.SATOSHIS_PER_BITCOIN / 1000; private final long noInputsFee; diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/MaxUtxoSelector.java b/src/main/java/com/sparrowwallet/drongo/wallet/MaxUtxoSelector.java index ad14bbd..0c8dd7c 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/MaxUtxoSelector.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/MaxUtxoSelector.java @@ -3,7 +3,7 @@ package com.sparrowwallet.drongo.wallet; import java.util.Collection; import java.util.stream.Collectors; -public class MaxUtxoSelector implements UtxoSelector { +public class MaxUtxoSelector extends SingleSetUtxoSelector { @Override public Collection select(long targetValue, Collection candidates) { return candidates.stream().filter(outputGroup -> outputGroup.getEffectiveValue() >= 0).flatMap(outputGroup -> outputGroup.getUtxos().stream()).collect(Collectors.toUnmodifiableList()); diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/Payment.java b/src/main/java/com/sparrowwallet/drongo/wallet/Payment.java index 18f2d99..1145f97 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/Payment.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/Payment.java @@ -57,6 +57,6 @@ public class Payment { } public enum Type { - DEFAULT, WHIRLPOOL_FEE; + DEFAULT, WHIRLPOOL_FEE, FAKE_MIX; } } diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/PresetUtxoSelector.java b/src/main/java/com/sparrowwallet/drongo/wallet/PresetUtxoSelector.java index da48706..2ad8147 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/PresetUtxoSelector.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/PresetUtxoSelector.java @@ -5,7 +5,7 @@ import java.util.Collection; import java.util.List; import java.util.stream.Collectors; -public class PresetUtxoSelector implements UtxoSelector { +public class PresetUtxoSelector extends SingleSetUtxoSelector { private final Collection presetUtxos; public PresetUtxoSelector(Collection presetUtxos) { diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/PriorityUtxoSelector.java b/src/main/java/com/sparrowwallet/drongo/wallet/PriorityUtxoSelector.java index 3ca1125..6d5d297 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/PriorityUtxoSelector.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/PriorityUtxoSelector.java @@ -4,7 +4,7 @@ import java.math.BigInteger; import java.util.*; import java.util.stream.Collectors; -public class PriorityUtxoSelector implements UtxoSelector { +public class PriorityUtxoSelector extends SingleSetUtxoSelector { private final int currentBlockHeight; public PriorityUtxoSelector(int currentBlockHeight) { diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/SingleSetUtxoSelector.java b/src/main/java/com/sparrowwallet/drongo/wallet/SingleSetUtxoSelector.java new file mode 100644 index 0000000..f28175e --- /dev/null +++ b/src/main/java/com/sparrowwallet/drongo/wallet/SingleSetUtxoSelector.java @@ -0,0 +1,13 @@ +package com.sparrowwallet.drongo.wallet; + +import java.util.Collection; +import java.util.List; + +public abstract class SingleSetUtxoSelector implements UtxoSelector { + @Override + public List> selectSets(long targetValue, Collection candidates) { + return List.of(select(targetValue, candidates)); + } + + public abstract Collection select(long targetValue, Collection candidates); +} diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/StonewallUtxoSelector.java b/src/main/java/com/sparrowwallet/drongo/wallet/StonewallUtxoSelector.java new file mode 100644 index 0000000..7ef194d --- /dev/null +++ b/src/main/java/com/sparrowwallet/drongo/wallet/StonewallUtxoSelector.java @@ -0,0 +1,76 @@ +package com.sparrowwallet.drongo.wallet; + +import java.util.*; +import java.util.stream.Collectors; + +public class StonewallUtxoSelector implements UtxoSelector { + private final long noInputsFee; + + //Use the same seed so the UTXO selection is deterministic + private final Random random = new Random(42); + + public StonewallUtxoSelector(long noInputsFee) { + this.noInputsFee = noInputsFee; + } + + @Override + public List> selectSets(long targetValue, Collection candidates) { + long actualTargetValue = targetValue + noInputsFee; + + for(int i = 0; i < 10; i++) { + List randomized = new ArrayList<>(candidates); + Collections.shuffle(randomized, random); + + List set1 = new ArrayList<>(); + long selectedValue1 = getUtxoSet(actualTargetValue, set1, randomized); + + List set2 = new ArrayList<>(); + long selectedValue2 = getUtxoSet(actualTargetValue, set2, randomized); + + if(selectedValue1 >= targetValue && selectedValue2 >= targetValue) { + return List.of(getUtxos(set1), getUtxos(set2)); + } + } + + return Collections.emptyList(); + } + + private long getUtxoSet(long targetValue, List selectedSet, List randomized) { + long selectedValue = 0; + while(selectedValue <= targetValue && !randomized.isEmpty()) { + OutputGroup candidate = randomized.remove(0); + + OutputGroup existingTxGroup = getTransactionAlreadySelected(selectedSet, candidate); + if(existingTxGroup != null) { + if(candidate.getValue() > existingTxGroup.getValue()) { + selectedSet.remove(existingTxGroup); + selectedSet.add(candidate); + } + } else { + selectedSet.add(candidate); + } + + selectedValue = selectedSet.stream().mapToLong(OutputGroup::getEffectiveValue).sum(); + } + + return selectedValue; + } + + private OutputGroup getTransactionAlreadySelected(List selected, OutputGroup candidateGroup) { + for(OutputGroup selectedGroup : selected) { + for(BlockTransactionHashIndex selectedUtxo : selectedGroup.getUtxos()) { + for(BlockTransactionHashIndex candidateUtxo : candidateGroup.getUtxos()) { + if(selectedUtxo.getHash().equals(candidateUtxo.getHash())) { + return selectedGroup; + } + } + } + } + + return null; + } + + private Collection getUtxos(List set) { + return set.stream().flatMap(outputGroup -> outputGroup.getUtxos().stream()).collect(Collectors.toList()); + } +} diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/UtxoSelector.java b/src/main/java/com/sparrowwallet/drongo/wallet/UtxoSelector.java index ca2e277..0051ba0 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/UtxoSelector.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/UtxoSelector.java @@ -1,7 +1,8 @@ package com.sparrowwallet.drongo.wallet; import java.util.Collection; +import java.util.List; public interface UtxoSelector { - Collection select(long targetValue, Collection candidates); + List> selectSets(long targetValue, Collection candidates); } diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java index aaf1078..2b137c3 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java @@ -622,7 +622,7 @@ public class Wallet extends Persistable { return getFee(changeOutput, feeRate, longTermFeeRate); } - public WalletTransaction createWalletTransaction(List utxoSelectors, List utxoFilters, List payments, List excludedChangeNodes, double feeRate, double longTermFeeRate, Long fee, Integer currentBlockHeight, boolean groupByAddress, boolean includeMempoolOutputs, boolean includeSpentMempoolOutputs) throws InsufficientFundsException { + public WalletTransaction createWalletTransaction(List utxoSelectors, List utxoFilters, List payments, Set excludedChangeNodes, double feeRate, double longTermFeeRate, Long fee, Integer currentBlockHeight, boolean groupByAddress, boolean includeMempoolOutputs, boolean includeSpentMempoolOutputs) throws InsufficientFundsException { boolean sendMax = payments.stream().anyMatch(Payment::isSendMax); long totalPaymentAmount = payments.stream().map(Payment::getAmount).mapToLong(v -> v).sum(); long totalUtxoValue = getWalletUtxos().keySet().stream().mapToLong(BlockTransactionHashIndex::getValue).sum(); @@ -644,8 +644,13 @@ public class Wallet extends Persistable { } while(true) { - Map selectedUtxos = selectInputs(utxoSelectors, utxoFilters, valueRequiredAmt, feeRate, longTermFeeRate, groupByAddress, includeMempoolOutputs, includeSpentMempoolOutputs, sendMax); + List> selectedUtxoSets = selectInputSets(utxoSelectors, utxoFilters, valueRequiredAmt, feeRate, longTermFeeRate, groupByAddress, includeMempoolOutputs, includeSpentMempoolOutputs, sendMax); + Map selectedUtxos = new HashMap<>(); + selectedUtxoSets.forEach(selectedUtxos::putAll); long totalSelectedAmt = selectedUtxos.keySet().stream().mapToLong(BlockTransactionHashIndex::getValue).sum(); + int numSets = selectedUtxoSets.size(); + List txPayments = new ArrayList<>(payments); + Set txExcludedChangeNodes = new HashSet<>(excludedChangeNodes); Transaction transaction = new Transaction(); transaction.setVersion(2); @@ -663,8 +668,16 @@ public class Wallet extends Persistable { txInput.setSequenceNumber(TransactionInput.SEQUENCE_RBF_ENABLED); } + for(int i = 1; i < numSets; i+=2) { + WalletNode mixNode = getFreshNode(KeyPurpose.CHANGE); + txExcludedChangeNodes.add(mixNode); + Payment fakeMixPayment = new Payment(getAddress(mixNode), ".." + mixNode + " (Fake Mix)", totalPaymentAmount, false); + fakeMixPayment.setType(Payment.Type.FAKE_MIX); + txPayments.add(fakeMixPayment); + } + //Add recipient outputs - for(Payment payment : payments) { + for(Payment payment : txPayments) { transaction.addOutput(payment.getAmount(), payment.getAddress()); } @@ -689,7 +702,7 @@ public class Wallet extends Persistable { } //Calculate what is left over from selected utxos after paying recipient - long differenceAmt = totalSelectedAmt - totalPaymentAmount; + long differenceAmt = totalSelectedAmt - totalPaymentAmount * numSets; //If insufficient fee, increase value required from inputs to include the fee and try again if(differenceAmt < noChangeFeeRequiredAmt) { @@ -703,38 +716,63 @@ public class Wallet extends Persistable { } //Determine if a change output is required by checking if its value is greater than its dust threshold - long changeAmt = differenceAmt - noChangeFeeRequiredAmt; + List setChangeAmts = getSetChangeAmounts(selectedUtxoSets, totalPaymentAmount, noChangeFeeRequiredAmt); double noChangeFeeRate = (fee == null ? feeRate : noChangeFeeRequiredAmt / transaction.getVirtualSize()); long costOfChangeAmt = getCostOfChange(noChangeFeeRate, longTermFeeRate); - if(changeAmt > costOfChangeAmt) { + if(setChangeAmts.stream().allMatch(amt -> amt > costOfChangeAmt)) { //Change output is required, determine new fee once change output has been added WalletNode changeNode = getFreshNode(KeyPurpose.CHANGE); - while(excludedChangeNodes.contains(changeNode)) { + while(txExcludedChangeNodes.contains(changeNode)) { changeNode = getFreshNode(KeyPurpose.CHANGE, changeNode); } - TransactionOutput changeOutput = new TransactionOutput(transaction, changeAmt, getOutputScript(changeNode)); - double changeVSize = noChangeVSize + changeOutput.getLength(); + TransactionOutput changeOutput = new TransactionOutput(transaction, setChangeAmts.iterator().next(), getOutputScript(changeNode)); + double changeVSize = noChangeVSize + changeOutput.getLength() * numSets; long changeFeeRequiredAmt = (fee == null ? (long)Math.floor(feeRate * changeVSize) : fee); changeFeeRequiredAmt = (fee == null && feeRate == Transaction.DEFAULT_MIN_RELAY_FEE ? changeFeeRequiredAmt + 1 : changeFeeRequiredAmt); - - //Recalculate the change amount with the new fee - changeAmt = differenceAmt - changeFeeRequiredAmt; - if(changeAmt < costOfChangeAmt) { - //The new fee has meant that the change output is now dust. We pay too high a fee without change, but change is dust when added. Increase value required from inputs and try again - valueRequiredAmt = totalSelectedAmt + 1; - continue; + while(changeFeeRequiredAmt % numSets > 0) { + changeFeeRequiredAmt++; } - //Add change output - transaction.addOutput(changeAmt, getOutputScript(changeNode)); + //Add change output(s) + Map changeMap = new LinkedHashMap<>(); + setChangeAmts = getSetChangeAmounts(selectedUtxoSets, totalPaymentAmount, changeFeeRequiredAmt); + for(Long setChangeAmt : setChangeAmts) { + transaction.addOutput(setChangeAmt, getOutputScript(changeNode)); + changeMap.put(changeNode, setChangeAmt); + changeNode = getFreshNode(KeyPurpose.CHANGE, changeNode); + } - return new WalletTransaction(this, transaction, utxoSelectors, selectedUtxos, payments, changeNode, changeAmt, changeFeeRequiredAmt); + if(setChangeAmts.stream().anyMatch(amt -> amt < costOfChangeAmt)) { + //The new fee has meant that one of the change outputs is now dust. We pay too high a fee without change, but change is dust when added. + if(numSets > 1) { + //Maximize privacy. Pay a higher fee to keep multiple output sets. + return new WalletTransaction(this, transaction, utxoSelectors, selectedUtxos, txPayments, differenceAmt); + } else { + //Maxmize efficiency. Increase value required from inputs and try again. + valueRequiredAmt = totalSelectedAmt + 1; + continue; + } + } + + return new WalletTransaction(this, transaction, utxoSelectors, selectedUtxos, txPayments, changeMap, changeFeeRequiredAmt); } - return new WalletTransaction(this, transaction, utxoSelectors, selectedUtxos, payments, differenceAmt); + return new WalletTransaction(this, transaction, utxoSelectors, selectedUtxos, txPayments, differenceAmt); } } + private List getSetChangeAmounts(List> selectedUtxoSets, long totalPaymentAmount, long feeRequiredAmt) { + List changeAmts = new ArrayList<>(); + int numSets = selectedUtxoSets.size(); + for(Map selectedUtxoSet : selectedUtxoSets) { + long setAmt = selectedUtxoSet.keySet().stream().mapToLong(BlockTransactionHashIndex::getValue).sum(); + long setChangeAmt = setAmt - (totalPaymentAmount + feeRequiredAmt / numSets); + changeAmts.add(setChangeAmt); + } + + return changeAmts; + } + public TransactionInput addDummySpendingInput(Transaction transaction, WalletNode walletNode, TransactionOutput prevTxOut) { if(getPolicyType().equals(PolicyType.SINGLE)) { ECKey pubKey = getPubKey(walletNode); @@ -752,7 +790,7 @@ public class Wallet extends Persistable { } } - private Map selectInputs(List utxoSelectors, List utxoFilters, Long targetValue, double feeRate, double longTermFeeRate, boolean groupByAddress, boolean includeMempoolOutputs, boolean includeSpentMempoolOutputs, boolean sendMax) throws InsufficientFundsException { + private List> selectInputSets(List utxoSelectors, List utxoFilters, Long targetValue, double feeRate, double longTermFeeRate, boolean groupByAddress, boolean includeMempoolOutputs, boolean includeSpentMempoolOutputs, boolean sendMax) throws InsufficientFundsException { List utxoPool = getGroupedUtxos(utxoFilters, feeRate, longTermFeeRate, groupByAddress, includeSpentMempoolOutputs); List filters = new ArrayList<>(); @@ -770,12 +808,19 @@ public class Wallet extends Persistable { List filteredPool = utxoPool.stream().filter(filter::isEligible).collect(Collectors.toList()); for(UtxoSelector utxoSelector : utxoSelectors) { - Collection selectedInputs = utxoSelector.select(targetValue, filteredPool); - long total = selectedInputs.stream().mapToLong(BlockTransactionHashIndex::getValue).sum(); - if(total > targetValue) { - Map utxos = getWalletUtxos(includeSpentMempoolOutputs); - utxos.keySet().retainAll(selectedInputs); - return utxos; + List> selectedInputSets = utxoSelector.selectSets(targetValue, filteredPool); + List> selectedInputSetsList = new ArrayList<>(); + long total = 0; + Map utxos = getWalletUtxos(includeSpentMempoolOutputs); + for(Collection selectedInputs : selectedInputSets) { + total += selectedInputs.stream().mapToLong(BlockTransactionHashIndex::getValue).sum(); + Map selectedInputsMap = new HashMap<>(utxos); + selectedInputsMap.keySet().retainAll(selectedInputs); + selectedInputSetsList.add(selectedInputsMap); + } + + if(total > targetValue * selectedInputSetsList.size()) { + return selectedInputSetsList; } } } diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/WalletTransaction.java b/src/main/java/com/sparrowwallet/drongo/wallet/WalletTransaction.java index e6aa32e..31c0339 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/WalletTransaction.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/WalletTransaction.java @@ -5,6 +5,7 @@ import com.sparrowwallet.drongo.protocol.Transaction; import com.sparrowwallet.drongo.psbt.PSBT; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.Map; @@ -18,22 +19,20 @@ public class WalletTransaction { private final List utxoSelectors; private final Map selectedUtxos; private final List payments; - private final WalletNode changeNode; - private final long changeAmount; + private final Map changeMap; private final long fee; public WalletTransaction(Wallet wallet, Transaction transaction, List utxoSelectors, Map selectedUtxos, List payments, long fee) { - this(wallet, transaction, utxoSelectors, selectedUtxos, payments, null, 0L, fee); + this(wallet, transaction, utxoSelectors, selectedUtxos, payments, Collections.emptyMap(), fee); } - public WalletTransaction(Wallet wallet, Transaction transaction, List utxoSelectors, Map selectedUtxos, List payments, WalletNode changeNode, long changeAmount, long fee) { + public WalletTransaction(Wallet wallet, Transaction transaction, List utxoSelectors, Map selectedUtxos, List payments, Map changeMap, long fee) { this.wallet = wallet; this.transaction = transaction; this.utxoSelectors = utxoSelectors; this.selectedUtxos = selectedUtxos; this.payments = payments; - this.changeNode = changeNode; - this.changeAmount = changeAmount; + this.changeMap = changeMap; this.fee = fee; } @@ -61,16 +60,12 @@ public class WalletTransaction { return payments; } - public WalletNode getChangeNode() { - return changeNode; + public Map getChangeMap() { + return changeMap; } - public Address getChangeAddress() { - return getWallet().getAddress(getChangeNode()); - } - - public long getChangeAmount() { - return changeAmount; + public Address getChangeAddress(WalletNode changeNode) { + return getWallet().getAddress(changeNode); } public long getFee() { From 67836b2b557839317316a3e1c8d18b98a51d0e29 Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Wed, 1 Sep 2021 13:08:18 +0200 Subject: [PATCH 058/155] add mix config to wallet --- .../drongo/wallet/MixConfig.java | 66 +++++++++++++++++++ .../sparrowwallet/drongo/wallet/Wallet.java | 21 ++++++ 2 files changed, 87 insertions(+) create mode 100644 src/main/java/com/sparrowwallet/drongo/wallet/MixConfig.java diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/MixConfig.java b/src/main/java/com/sparrowwallet/drongo/wallet/MixConfig.java new file mode 100644 index 0000000..63016bb --- /dev/null +++ b/src/main/java/com/sparrowwallet/drongo/wallet/MixConfig.java @@ -0,0 +1,66 @@ +package com.sparrowwallet.drongo.wallet; + +import java.io.File; + +public class MixConfig extends Persistable { + private String scode; + private Boolean mixOnStartup; + private File mixToWalletFile; + private String mixToWalletName; + private Integer minMixes; + + public MixConfig() { + } + + public MixConfig(String scode, Boolean mixOnStartup, File mixToWalletFile, String mixToWalletName, Integer minMixes) { + this.scode = scode; + this.mixOnStartup = mixOnStartup; + this.mixToWalletFile = mixToWalletFile; + this.mixToWalletName = mixToWalletName; + this.minMixes = minMixes; + } + + public String getScode() { + return scode; + } + + public void setScode(String scode) { + this.scode = scode; + } + + public Boolean getMixOnStartup() { + return mixOnStartup; + } + + public void setMixOnStartup(Boolean mixOnStartup) { + this.mixOnStartup = mixOnStartup; + } + + public File getMixToWalletFile() { + return mixToWalletFile; + } + + public void setMixToWalletFile(File mixToWalletFile) { + this.mixToWalletFile = mixToWalletFile; + } + + public String getMixToWalletName() { + return mixToWalletName; + } + + public void setMixToWalletName(String mixToWalletName) { + this.mixToWalletName = mixToWalletName; + } + + public Integer getMinMixes() { + return minMixes; + } + + public void setMinMixes(Integer minMixes) { + this.minMixes = minMixes; + } + + public MixConfig copy() { + return new MixConfig(scode, mixOnStartup, mixToWalletFile, mixToWalletName, minMixes); + } +} diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java index a443a39..1db5590 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java @@ -36,6 +36,7 @@ public class Wallet extends Persistable { private List keystores = new ArrayList<>(); private final TreeSet purposeNodes = new TreeSet<>(); private final Map transactions = new HashMap<>(); + private MixConfig mixConfig; private final Map utxoMixes = new HashMap<>(); private Integer storedBlockHeight; private Integer gapLimit; @@ -230,6 +231,22 @@ public class Wallet extends Persistable { } } + public MixConfig getMixConfig() { + return mixConfig; + } + + public MixConfig getOrCreateMixConfig() { + if(mixConfig == null) { + mixConfig = new MixConfig(); + } + + return mixConfig; + } + + public void setMixConfig(MixConfig mixConfig) { + this.mixConfig = mixConfig; + } + public UtxoMixData getUtxoMixData(BlockTransactionHashIndex utxo) { return getUtxoMixData(Sha256Hash.of(utxo.toString().getBytes(StandardCharsets.UTF_8))); } @@ -1339,6 +1356,10 @@ public class Wallet extends Persistable { for(Sha256Hash hash : transactions.keySet()) { copy.transactions.put(hash, transactions.get(hash)); } + copy.setMixConfig(mixConfig == null ? null : mixConfig.copy()); + for(Sha256Hash hash : utxoMixes.keySet()) { + copy.utxoMixes.put(hash, utxoMixes.get(hash)); + } copy.setStoredBlockHeight(getStoredBlockHeight()); copy.gapLimit = gapLimit; copy.birthDate = birthDate; From b4f4cc8726de3e7b5f875816affe1e0f78f2fa25 Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Thu, 2 Sep 2021 11:39:33 +0200 Subject: [PATCH 059/155] improve mix config retrieval --- src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java index 1db5590..431b81a 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java @@ -235,7 +235,11 @@ public class Wallet extends Persistable { return mixConfig; } - public MixConfig getOrCreateMixConfig() { + public MixConfig getMasterMixConfig() { + if(!isMasterWallet()) { + return getMasterWallet().getMasterMixConfig(); + } + if(mixConfig == null) { mixConfig = new MixConfig(); } From 94d22b875868760a95222e0254ec10b59c71e04f Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Thu, 2 Sep 2021 14:11:51 +0200 Subject: [PATCH 060/155] store mix indexes in mixconfig --- .../drongo/wallet/MixConfig.java | 24 +++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/MixConfig.java b/src/main/java/com/sparrowwallet/drongo/wallet/MixConfig.java index 63016bb..26062b6 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/MixConfig.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/MixConfig.java @@ -8,16 +8,20 @@ public class MixConfig extends Persistable { private File mixToWalletFile; private String mixToWalletName; private Integer minMixes; + private int receiveIndex; + private int changeIndex; public MixConfig() { } - public MixConfig(String scode, Boolean mixOnStartup, File mixToWalletFile, String mixToWalletName, Integer minMixes) { + public MixConfig(String scode, Boolean mixOnStartup, File mixToWalletFile, String mixToWalletName, Integer minMixes, int receiveIndex, int changeIndex) { this.scode = scode; this.mixOnStartup = mixOnStartup; this.mixToWalletFile = mixToWalletFile; this.mixToWalletName = mixToWalletName; this.minMixes = minMixes; + this.receiveIndex = receiveIndex; + this.changeIndex = changeIndex; } public String getScode() { @@ -60,7 +64,23 @@ public class MixConfig extends Persistable { this.minMixes = minMixes; } + public int getReceiveIndex() { + return receiveIndex; + } + + public void setReceiveIndex(int receiveIndex) { + this.receiveIndex = receiveIndex; + } + + public int getChangeIndex() { + return changeIndex; + } + + public void setChangeIndex(int changeIndex) { + this.changeIndex = changeIndex; + } + public MixConfig copy() { - return new MixConfig(scode, mixOnStartup, mixToWalletFile, mixToWalletName, minMixes); + return new MixConfig(scode, mixOnStartup, mixToWalletFile, mixToWalletName, minMixes, receiveIndex, changeIndex); } } From 0b40c20ab252e29ac192bca34d834b8c3eed04a0 Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Fri, 3 Sep 2021 17:12:58 +0200 Subject: [PATCH 061/155] support required script types on child wallets --- .../drongo/wallet/StandardAccount.java | 19 ++++++++++++++++--- .../sparrowwallet/drongo/wallet/Wallet.java | 8 ++++++-- 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/StandardAccount.java b/src/main/java/com/sparrowwallet/drongo/wallet/StandardAccount.java index 4d66905..5c3be3d 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/StandardAccount.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/StandardAccount.java @@ -1,6 +1,7 @@ package com.sparrowwallet.drongo.wallet; import com.sparrowwallet.drongo.crypto.ChildNumber; +import com.sparrowwallet.drongo.protocol.ScriptType; import java.util.List; @@ -15,9 +16,9 @@ public enum StandardAccount { ACCOUNT_7("Account #7", new ChildNumber(7, true)), ACCOUNT_8("Account #8", new ChildNumber(8, true)), ACCOUNT_9("Account #9", new ChildNumber(9, true)), - WHIRLPOOL_PREMIX("Premix", new ChildNumber(2147483645, true)), - WHIRLPOOL_POSTMIX("Postmix", new ChildNumber(2147483646, true)), - WHIRLPOOL_BADBANK("Badbank", new ChildNumber(2147483644, true)); + WHIRLPOOL_PREMIX("Premix", new ChildNumber(2147483645, true), ScriptType.P2WPKH), + WHIRLPOOL_POSTMIX("Postmix", new ChildNumber(2147483646, true), ScriptType.P2WPKH), + WHIRLPOOL_BADBANK("Badbank", new ChildNumber(2147483644, true), ScriptType.P2WPKH); public static final List WHIRLPOOL_ACCOUNTS = List.of(WHIRLPOOL_PREMIX, WHIRLPOOL_POSTMIX, WHIRLPOOL_BADBANK); public static final List WHIRLPOOL_MIX_ACCOUNTS = List.of(WHIRLPOOL_PREMIX, WHIRLPOOL_POSTMIX); @@ -25,10 +26,18 @@ public enum StandardAccount { StandardAccount(String name, ChildNumber childNumber) { this.name = name; this.childNumber = childNumber; + this.requiredScriptType = null; + } + + StandardAccount(String name, ChildNumber childNumber, ScriptType requiredScriptType) { + this.name = name; + this.childNumber = childNumber; + this.requiredScriptType = requiredScriptType; } private final String name; private final ChildNumber childNumber; + private final ScriptType requiredScriptType; public String getName() { return name; @@ -42,6 +51,10 @@ public enum StandardAccount { return childNumber.num(); } + public ScriptType getRequiredScriptType() { + return requiredScriptType; + } + @Override public String toString() { return name; diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java index 431b81a..4c1581c 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java @@ -105,9 +105,13 @@ public class Wallet extends Persistable { childWallet.gapLimit = null; childWallet.birthDate = null; + if(standardAccount.getRequiredScriptType() != null) { + childWallet.setScriptType(standardAccount.getRequiredScriptType()); + } + for(Keystore keystore : childWallet.getKeystores()) { - KeyDerivation keyDerivation = keystore.getKeyDerivation(); - List childDerivation = new ArrayList<>(keyDerivation.getDerivation().subList(0, keyDerivation.getDerivation().size() - 1)); + List derivation = standardAccount.getRequiredScriptType() != null ? standardAccount.getRequiredScriptType().getDefaultDerivation() : keystore.getKeyDerivation().getDerivation(); + List childDerivation = new ArrayList<>(derivation.subList(0, derivation.size() - 1)); childDerivation.add(standardAccount.getChildNumber()); try { From 38783d68a49ecf5d8c8640edb299d693f455b2a9 Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Wed, 8 Sep 2021 13:21:04 +0200 Subject: [PATCH 062/155] support network dependent block height taproot activation --- src/main/java/com/sparrowwallet/drongo/Network.java | 2 ++ .../java/com/sparrowwallet/drongo/protocol/ScriptType.java | 7 ++++--- src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java | 4 ++++ 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/sparrowwallet/drongo/Network.java b/src/main/java/com/sparrowwallet/drongo/Network.java index 06c6917..de3782a 100644 --- a/src/main/java/com/sparrowwallet/drongo/Network.java +++ b/src/main/java/com/sparrowwallet/drongo/Network.java @@ -6,6 +6,8 @@ public enum Network { REGTEST("regtest", 111, "mn", 196, "2", "bcrt", ExtendedKey.Header.tprv, ExtendedKey.Header.tpub, 18443), SIGNET("signet", 111, "mn", 196, "2", "tb", ExtendedKey.Header.tprv, ExtendedKey.Header.tpub, 38332); + public static final String BLOCK_HEIGHT_PROPERTY = "com.sparrowwallet.blockHeight"; + Network(String name, int p2pkhAddressHeader, String p2pkhAddressPrefix, int p2shAddressHeader, String p2shAddressPrefix, String bech32AddressHrp, ExtendedKey.Header xprvHeader, ExtendedKey.Header xpubHeader, int defaultPort) { this.name = name; this.p2pkhAddressHeader = p2pkhAddressHeader; diff --git a/src/main/java/com/sparrowwallet/drongo/protocol/ScriptType.java b/src/main/java/com/sparrowwallet/drongo/protocol/ScriptType.java index cc4260d..cf849cf 100644 --- a/src/main/java/com/sparrowwallet/drongo/protocol/ScriptType.java +++ b/src/main/java/com/sparrowwallet/drongo/protocol/ScriptType.java @@ -1134,12 +1134,13 @@ public enum ScriptType { @Override public List getAllowedPolicyTypes() { - return (Network.get() == Network.MAINNET && LocalDate.now().isAfter(TAPROOT_MAINNET_ACTIVATION_DATE)) || Network.get() == Network.TESTNET || Network.get() == Network.REGTEST || Network.get() == Network.SIGNET ? List.of(SINGLE) : Collections.emptyList(); + return (Network.get() == Network.MAINNET && LocalDate.now().isAfter(TAPROOT_MAINNET_ACTIVATION_DATE) || (System.getProperty(Network.BLOCK_HEIGHT_PROPERTY) != null && Integer.parseInt(System.getProperty(Network.BLOCK_HEIGHT_PROPERTY)) >= 709632)) + || Network.get() == Network.TESTNET || Network.get() == Network.REGTEST || Network.get() == Network.SIGNET ? List.of(SINGLE) : Collections.emptyList(); } }; - //To avoid relying on a network-dependent block height >= 709632 check, use a approximate activation date. This can be removed once Taproot has activated on mainnet. - private static final LocalDate TAPROOT_MAINNET_ACTIVATION_DATE = LocalDate.of(2021, Month.NOVEMBER, 22); + //To avoid relying solely on a network-dependent block height >= 709632 check, use a approximate activation date. This can be removed once Taproot has activated on mainnet. + private static final LocalDate TAPROOT_MAINNET_ACTIVATION_DATE = LocalDate.of(2021, Month.NOVEMBER, 17); private final String name; private final String description; diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java index 4c1581c..1484f90 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java @@ -174,6 +174,10 @@ public class Wallet extends Persistable { return whirlpoolAccounts.isEmpty(); } + public boolean isWhirlpoolChildWallet() { + return !isMasterWallet() && StandardAccount.WHIRLPOOL_ACCOUNTS.contains(getStandardAccountType()); + } + public boolean isWhirlpoolMixWallet() { return !isMasterWallet() && StandardAccount.WHIRLPOOL_MIX_ACCOUNTS.contains(getStandardAccountType()); } From c9e57fad018750a150a563cd17c8872d7cda48f0 Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Wed, 22 Sep 2021 16:31:06 +0200 Subject: [PATCH 063/155] add privacy-focused anti-fee-sniping recommendations for taproot transactions --- .../sparrowwallet/drongo/wallet/Wallet.java | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java index 1484f90..8069392 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java @@ -701,6 +701,10 @@ public class Wallet extends Persistable { txInput.setSequenceNumber(TransactionInput.SEQUENCE_RBF_ENABLED); } + if(getScriptType() == P2TR && currentBlockHeight != null) { + applySequenceAntiFeeSniping(transaction, selectedUtxos, currentBlockHeight); + } + for(int i = 1; i < numSets; i+=2) { WalletNode mixNode = getFreshNode(KeyPurpose.CHANGE); txExcludedChangeNodes.add(mixNode); @@ -794,6 +798,27 @@ public class Wallet extends Persistable { } } + private void applySequenceAntiFeeSniping(Transaction transaction, Map selectedUtxos, int currentBlockHeight) { + Random random = new Random(); + boolean locktime = random.nextInt(2) == 0 || getScriptType() != P2TR || selectedUtxos.keySet().stream().anyMatch(utxo -> utxo.getConfirmations(currentBlockHeight) > 65535); + + if(locktime) { + transaction.setLocktime(currentBlockHeight); + if(random.nextInt(10) == 0) { + transaction.setLocktime(Math.max(0, currentBlockHeight - random.nextInt(100))); + } + } else { + transaction.setLocktime(0); + int inputIndex = random.nextInt(transaction.getInputs().size()); + TransactionInput txInput = transaction.getInputs().get(inputIndex); + BlockTransactionHashIndex utxo = selectedUtxos.keySet().stream().filter(ref -> ref.getHash().equals(txInput.getOutpoint().getHash()) && ref.getIndex() == txInput.getOutpoint().getIndex()).findFirst().orElseThrow(); + txInput.setSequenceNumber(utxo.getConfirmations(currentBlockHeight)); + if(random.nextInt(10) == 0) { + txInput.setSequenceNumber(Math.max(0, txInput.getSequenceNumber() - random.nextInt(100))); + } + } + } + private List getSetChangeAmounts(List> selectedUtxoSets, long totalPaymentAmount, long feeRequiredAmt) { List changeAmts = new ArrayList<>(); int numSets = selectedUtxoSets.size(); From 9a9a1b925461ee2a8ae7f6885309b0babd4b6767 Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Wed, 29 Sep 2021 10:11:07 +0200 Subject: [PATCH 064/155] support add child wallets from all wallet types, double postmix gap limit --- .../drongo/wallet/StandardAccount.java | 15 ++++-- .../sparrowwallet/drongo/wallet/Wallet.java | 53 +++++++++++++------ 2 files changed, 47 insertions(+), 21 deletions(-) diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/StandardAccount.java b/src/main/java/com/sparrowwallet/drongo/wallet/StandardAccount.java index 5c3be3d..238498c 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/StandardAccount.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/StandardAccount.java @@ -16,9 +16,9 @@ public enum StandardAccount { ACCOUNT_7("Account #7", new ChildNumber(7, true)), ACCOUNT_8("Account #8", new ChildNumber(8, true)), ACCOUNT_9("Account #9", new ChildNumber(9, true)), - WHIRLPOOL_PREMIX("Premix", new ChildNumber(2147483645, true), ScriptType.P2WPKH), - WHIRLPOOL_POSTMIX("Postmix", new ChildNumber(2147483646, true), ScriptType.P2WPKH), - WHIRLPOOL_BADBANK("Badbank", new ChildNumber(2147483644, true), ScriptType.P2WPKH); + WHIRLPOOL_PREMIX("Premix", new ChildNumber(2147483645, true), ScriptType.P2WPKH, null), + WHIRLPOOL_POSTMIX("Postmix", new ChildNumber(2147483646, true), ScriptType.P2WPKH, Wallet.DEFAULT_LOOKAHEAD * 2), + WHIRLPOOL_BADBANK("Badbank", new ChildNumber(2147483644, true), ScriptType.P2WPKH, null); public static final List WHIRLPOOL_ACCOUNTS = List.of(WHIRLPOOL_PREMIX, WHIRLPOOL_POSTMIX, WHIRLPOOL_BADBANK); public static final List WHIRLPOOL_MIX_ACCOUNTS = List.of(WHIRLPOOL_PREMIX, WHIRLPOOL_POSTMIX); @@ -27,17 +27,20 @@ public enum StandardAccount { this.name = name; this.childNumber = childNumber; this.requiredScriptType = null; + this.minimumGapLimit = null; } - StandardAccount(String name, ChildNumber childNumber, ScriptType requiredScriptType) { + StandardAccount(String name, ChildNumber childNumber, ScriptType requiredScriptType, Integer minimumGapLimit) { this.name = name; this.childNumber = childNumber; this.requiredScriptType = requiredScriptType; + this.minimumGapLimit = minimumGapLimit; } private final String name; private final ChildNumber childNumber; private final ScriptType requiredScriptType; + private final Integer minimumGapLimit; public String getName() { return name; @@ -55,6 +58,10 @@ public enum StandardAccount { return requiredScriptType; } + public Integer getMinimumGapLimit() { + return minimumGapLimit; + } + @Override public String toString() { return name; diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java index 8069392..b1c04f1 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java @@ -22,7 +22,7 @@ import java.util.stream.Collectors; import static com.sparrowwallet.drongo.protocol.ScriptType.*; import static com.sparrowwallet.drongo.protocol.Transaction.WITNESS_SCALE_FACTOR; -public class Wallet extends Persistable { +public class Wallet extends Persistable implements Comparable { public static final int DEFAULT_LOOKAHEAD = 20; public static final String ALLOW_DERIVATIONS_MATCHING_OTHER_SCRIPT_TYPES_PROPERTY = "com.sparrowwallet.allowDerivationsMatchingOtherScriptTypes"; @@ -89,11 +89,7 @@ public class Wallet extends Persistable { throw new IllegalStateException("Cannot add child wallet to existing child wallet"); } - if(!childWallet.containsPrivateKeys()) { - throw new IllegalStateException("Cannot derive child wallet xpub without private keys"); - } - - if(childWallet.isEncrypted()) { + if(childWallet.containsPrivateKeys() && childWallet.isEncrypted()) { throw new IllegalStateException("Cannot derive child wallet xpub from encrypted wallet"); } @@ -102,7 +98,7 @@ public class Wallet extends Persistable { childWallet.purposeNodes.clear(); childWallet.transactions.clear(); childWallet.storedBlockHeight = null; - childWallet.gapLimit = null; + childWallet.gapLimit = standardAccount.getMinimumGapLimit(); childWallet.birthDate = null; if(standardAccount.getRequiredScriptType() != null) { @@ -111,16 +107,25 @@ public class Wallet extends Persistable { for(Keystore keystore : childWallet.getKeystores()) { List derivation = standardAccount.getRequiredScriptType() != null ? standardAccount.getRequiredScriptType().getDefaultDerivation() : keystore.getKeyDerivation().getDerivation(); - List childDerivation = new ArrayList<>(derivation.subList(0, derivation.size() - 1)); - childDerivation.add(standardAccount.getChildNumber()); + List childDerivation; + if(childWallet.getScriptType().getAccount(KeyDerivation.writePath(derivation)) > -1) { + childDerivation = childWallet.getScriptType().getDefaultDerivation(standardAccount.getChildNumber().num()); + } else { + childDerivation = derivation.isEmpty() ? new ArrayList<>() : new ArrayList<>(derivation.subList(0, derivation.size() - 1)); + childDerivation.add(standardAccount.getChildNumber()); + } - try { - Keystore derivedKeystore = Keystore.fromSeed(keystore.getSeed(), childDerivation); - keystore.setKeyDerivation(derivedKeystore.getKeyDerivation()); - keystore.setExtendedPublicKey(derivedKeystore.getExtendedPublicKey()); - keystore.getSeed().setPassphrase(keystore.getSeed().getPassphrase()); - } catch(Exception e) { - throw new IllegalStateException("Cannot derive keystore for " + standardAccount + " account", e); + if(keystore.hasPrivateKey()) { + try { + Keystore derivedKeystore = keystore.hasSeed() ? Keystore.fromSeed(keystore.getSeed(), childDerivation) : Keystore.fromMasterPrivateExtendedKey(keystore.getMasterPrivateExtendedKey(), childDerivation); + keystore.setKeyDerivation(derivedKeystore.getKeyDerivation()); + keystore.setExtendedPublicKey(derivedKeystore.getExtendedPublicKey()); + } catch(Exception e) { + throw new IllegalStateException("Cannot derive keystore for " + standardAccount + " account", e); + } + } else { + keystore.setKeyDerivation(new KeyDerivation(null, KeyDerivation.writePath(childDerivation))); + keystore.setExtendedPublicKey(null); } } @@ -154,6 +159,11 @@ public class Wallet extends Persistable { int keystoreAccount = getScriptType().getAccount(keystore.getKeyDerivation().getDerivationPath()); if(keystoreAccount != -1 && (index == -1 || keystoreAccount == index)) { index = keystoreAccount; + } else if(!keystore.getKeyDerivation().getDerivation().isEmpty()) { + keystoreAccount = keystore.getKeyDerivation().getDerivation().get(keystore.getKeyDerivation().getDerivation().size() - 1).num(); + if(index == -1 || keystoreAccount == index) { + index = keystoreAccount; + } } } } @@ -175,7 +185,7 @@ public class Wallet extends Persistable { } public boolean isWhirlpoolChildWallet() { - return !isMasterWallet() && StandardAccount.WHIRLPOOL_ACCOUNTS.contains(getStandardAccountType()); + return !isMasterWallet() && getStandardAccountType() != null && StandardAccount.WHIRLPOOL_ACCOUNTS.contains(getStandardAccountType()); } public boolean isWhirlpoolMixWallet() { @@ -1458,6 +1468,15 @@ public class Wallet extends Persistable { } } + @Override + public int compareTo(Wallet other) { + if(getStandardAccountType() != null && other.getStandardAccountType() != null) { + return getStandardAccountType().ordinal() - other.getStandardAccountType().ordinal(); + } + + return getAccountIndex() - other.getAccountIndex(); + } + @Override public String toString() { return getFullName(); From e0302cef22a3dd9401f9070318fec5ea15543bd7 Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Mon, 4 Oct 2021 12:15:37 +0200 Subject: [PATCH 065/155] increase postmix lookahead --- .../java/com/sparrowwallet/drongo/wallet/StandardAccount.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/StandardAccount.java b/src/main/java/com/sparrowwallet/drongo/wallet/StandardAccount.java index 238498c..b44a4ef 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/StandardAccount.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/StandardAccount.java @@ -17,7 +17,7 @@ public enum StandardAccount { ACCOUNT_8("Account #8", new ChildNumber(8, true)), ACCOUNT_9("Account #9", new ChildNumber(9, true)), WHIRLPOOL_PREMIX("Premix", new ChildNumber(2147483645, true), ScriptType.P2WPKH, null), - WHIRLPOOL_POSTMIX("Postmix", new ChildNumber(2147483646, true), ScriptType.P2WPKH, Wallet.DEFAULT_LOOKAHEAD * 2), + WHIRLPOOL_POSTMIX("Postmix", new ChildNumber(2147483646, true), ScriptType.P2WPKH, Wallet.DEFAULT_LOOKAHEAD * 3), WHIRLPOOL_BADBANK("Badbank", new ChildNumber(2147483644, true), ScriptType.P2WPKH, null); public static final List WHIRLPOOL_ACCOUNTS = List.of(WHIRLPOOL_PREMIX, WHIRLPOOL_POSTMIX, WHIRLPOOL_BADBANK); From 2fd7e8e7e417212c7b6555a463f25004650d3a01 Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Wed, 6 Oct 2021 08:22:30 +0200 Subject: [PATCH 066/155] add mnemonic seed type exception --- .../drongo/wallet/MnemonicException.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/MnemonicException.java b/src/main/java/com/sparrowwallet/drongo/wallet/MnemonicException.java index 02a1cb6..6155acf 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/MnemonicException.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/MnemonicException.java @@ -39,4 +39,16 @@ public class MnemonicException extends Exception { this.badWord = badWord; } } + + /** + * Thrown when the mnemonic is valid, but for for the expected standard + */ + public static class MnemonicTypeException extends MnemonicException { + public final DeterministicSeed.Type invalidType; + + public MnemonicTypeException(DeterministicSeed.Type invalidType) { + super(); + this.invalidType = invalidType; + } + } } From 025af0575899d6e255cc0a1f875cad25ab4811b8 Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Thu, 7 Oct 2021 12:28:54 +0200 Subject: [PATCH 067/155] postmix gap limit to 40 --- .../java/com/sparrowwallet/drongo/wallet/StandardAccount.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/StandardAccount.java b/src/main/java/com/sparrowwallet/drongo/wallet/StandardAccount.java index b44a4ef..238498c 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/StandardAccount.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/StandardAccount.java @@ -17,7 +17,7 @@ public enum StandardAccount { ACCOUNT_8("Account #8", new ChildNumber(8, true)), ACCOUNT_9("Account #9", new ChildNumber(9, true)), WHIRLPOOL_PREMIX("Premix", new ChildNumber(2147483645, true), ScriptType.P2WPKH, null), - WHIRLPOOL_POSTMIX("Postmix", new ChildNumber(2147483646, true), ScriptType.P2WPKH, Wallet.DEFAULT_LOOKAHEAD * 3), + WHIRLPOOL_POSTMIX("Postmix", new ChildNumber(2147483646, true), ScriptType.P2WPKH, Wallet.DEFAULT_LOOKAHEAD * 2), WHIRLPOOL_BADBANK("Badbank", new ChildNumber(2147483644, true), ScriptType.P2WPKH, null); public static final List WHIRLPOOL_ACCOUNTS = List.of(WHIRLPOOL_PREMIX, WHIRLPOOL_POSTMIX, WHIRLPOOL_BADBANK); From 61b2fd21e6f623850ad8b5df9f0cec4a0c0908cc Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Wed, 13 Oct 2021 15:20:22 +0200 Subject: [PATCH 068/155] add support for retrieving added nodes, refactor nodeRangeToString --- .../drongo/wallet/WalletNode.java | 74 ++++++++++++++++++- 1 file changed, 72 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/WalletNode.java b/src/main/java/com/sparrowwallet/drongo/wallet/WalletNode.java index d97cc17..fc699fd 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/WalletNode.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/WalletNode.java @@ -130,11 +130,16 @@ public class WalletNode extends Persistable implements Comparable { return value; } - public synchronized void fillToIndex(int index) { + public synchronized Set fillToIndex(int index) { + Set newNodes = new TreeSet<>(); for(int i = 0; i <= index; i++) { WalletNode node = new WalletNode(getKeyPurpose(), i); - children.add(node); + if(children.add(node)) { + newNodes.add(node); + } } + + return newNodes; } /** @@ -245,4 +250,69 @@ public class WalletNode extends Persistable implements Comparable { return changed; } + + public static String nodeRangesToString(Set nodes) { + return nodeRangesToString(nodes.stream().map(WalletNode::getDerivationPath).collect(Collectors.toList())); + } + + public static String nodeRangesToString(Collection nodeDerivations) { + List sortedDerivations = new ArrayList<>(nodeDerivations); + + if(nodeDerivations.isEmpty()) { + return "[]"; + } + + List> contiguous = splitToContiguous(sortedDerivations); + + String abbrev = "["; + for(Iterator> iter = contiguous.iterator(); iter.hasNext(); ) { + List range = iter.next(); + abbrev += range.get(0); + if(range.size() > 1) { + abbrev += "-" + range.get(range.size() - 1); + } + if(iter.hasNext()) { + abbrev += ", "; + } + } + abbrev += "]"; + + return abbrev; + } + + private static List> splitToContiguous(List input) { + List> result = new ArrayList<>(); + int prev = 0; + + int keyPurpose = getKeyPurpose(input.get(0)); + int index = getIndex(input.get(0)); + + for (int cur = 0; cur < input.size(); cur++) { + if(getKeyPurpose(input.get(cur)) != keyPurpose || getIndex(input.get(cur)) != index) { + result.add(input.subList(prev, cur)); + prev = cur; + } + index = getIndex(input.get(cur)) + 1; + keyPurpose = getKeyPurpose(input.get(cur)); + } + result.add(input.subList(prev, input.size())); + + return result; + } + + private static int getKeyPurpose(String path) { + List childNumbers = KeyDerivation.parsePath(path); + if(childNumbers.isEmpty()) { + return -1; + } + return childNumbers.get(0).num(); + } + + private static int getIndex(String path) { + List childNumbers = KeyDerivation.parsePath(path); + if(childNumbers.isEmpty()) { + return -1; + } + return childNumbers.get(childNumbers.size() - 1).num(); + } } From c04c24945000f8f3c702801cea1c9921cc60cbbd Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Thu, 14 Oct 2021 11:11:41 +0200 Subject: [PATCH 069/155] add mixable standard accounts list --- .../java/com/sparrowwallet/drongo/wallet/StandardAccount.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/StandardAccount.java b/src/main/java/com/sparrowwallet/drongo/wallet/StandardAccount.java index 238498c..bcc95d3 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/StandardAccount.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/StandardAccount.java @@ -20,6 +20,7 @@ public enum StandardAccount { WHIRLPOOL_POSTMIX("Postmix", new ChildNumber(2147483646, true), ScriptType.P2WPKH, Wallet.DEFAULT_LOOKAHEAD * 2), WHIRLPOOL_BADBANK("Badbank", new ChildNumber(2147483644, true), ScriptType.P2WPKH, null); + public static final List MIXABLE_ACCOUNTS = List.of(ACCOUNT_0, WHIRLPOOL_BADBANK); public static final List WHIRLPOOL_ACCOUNTS = List.of(WHIRLPOOL_PREMIX, WHIRLPOOL_POSTMIX, WHIRLPOOL_BADBANK); public static final List WHIRLPOOL_MIX_ACCOUNTS = List.of(WHIRLPOOL_PREMIX, WHIRLPOOL_POSTMIX); From 57290a20a143bc0f0d8440fb3c14592c2e204e6b Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Sat, 16 Oct 2021 11:09:30 +0200 Subject: [PATCH 070/155] add coin selection filter to exclude immature coinbase outputs --- .../drongo/protocol/Transaction.java | 1 + .../drongo/wallet/CoinbaseUtxoFilter.java | 23 +++++++++++++++++++ 2 files changed, 24 insertions(+) create mode 100644 src/main/java/com/sparrowwallet/drongo/wallet/CoinbaseUtxoFilter.java diff --git a/src/main/java/com/sparrowwallet/drongo/protocol/Transaction.java b/src/main/java/com/sparrowwallet/drongo/protocol/Transaction.java index fc86c24..c4ca948 100644 --- a/src/main/java/com/sparrowwallet/drongo/protocol/Transaction.java +++ b/src/main/java/com/sparrowwallet/drongo/protocol/Transaction.java @@ -23,6 +23,7 @@ public class Transaction extends ChildMessage { public static final long MAX_BLOCK_LOCKTIME = 500000000L; public static final int WITNESS_SCALE_FACTOR = 4; public static final int DEFAULT_SEGWIT_FLAG = 1; + public static final int COINBASE_MATURITY_THRESHOLD = 100; //Min feerate for defining dust, defined in sats/vByte //From: https://github.com/bitcoin/bitcoin/blob/0.19/src/policy/policy.h#L50 diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/CoinbaseUtxoFilter.java b/src/main/java/com/sparrowwallet/drongo/wallet/CoinbaseUtxoFilter.java new file mode 100644 index 0000000..92051c8 --- /dev/null +++ b/src/main/java/com/sparrowwallet/drongo/wallet/CoinbaseUtxoFilter.java @@ -0,0 +1,23 @@ +package com.sparrowwallet.drongo.wallet; + +import com.sparrowwallet.drongo.protocol.Transaction; + +public class CoinbaseUtxoFilter implements UtxoFilter { + private final Wallet wallet; + + public CoinbaseUtxoFilter(Wallet wallet) { + this.wallet = wallet; + } + + @Override + public boolean isEligible(BlockTransactionHashIndex candidate) { + //Disallow immature coinbase outputs + BlockTransaction blockTransaction = wallet.getTransactions().get(candidate.getHash()); + if(blockTransaction != null && blockTransaction.getTransaction() != null && blockTransaction.getTransaction().isCoinBase() + && wallet.getStoredBlockHeight() != null && candidate.getConfirmations(wallet.getStoredBlockHeight()) < Transaction.COINBASE_MATURITY_THRESHOLD) { + return false; + } + + return true; + } +} From eb49c9713375ac5f909d8ec3fa4dfddaf7d63ffe Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Fri, 22 Oct 2021 11:00:51 +0200 Subject: [PATCH 071/155] support adding op return data when creating wallet transactions --- src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java index b1c04f1..35a839e 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java @@ -665,7 +665,7 @@ public class Wallet extends Persistable implements Comparable { return getFee(changeOutput, feeRate, longTermFeeRate); } - public WalletTransaction createWalletTransaction(List utxoSelectors, List utxoFilters, List payments, Set excludedChangeNodes, double feeRate, double longTermFeeRate, Long fee, Integer currentBlockHeight, boolean groupByAddress, boolean includeMempoolOutputs, boolean includeSpentMempoolOutputs) throws InsufficientFundsException { + public WalletTransaction createWalletTransaction(List utxoSelectors, List utxoFilters, List payments, List opReturns, Set excludedChangeNodes, double feeRate, double longTermFeeRate, Long fee, Integer currentBlockHeight, boolean groupByAddress, boolean includeMempoolOutputs, boolean includeSpentMempoolOutputs) throws InsufficientFundsException { boolean sendMax = payments.stream().anyMatch(Payment::isSendMax); long totalPaymentAmount = payments.stream().map(Payment::getAmount).mapToLong(v -> v).sum(); long totalUtxoValue = getWalletUtxos().keySet().stream().mapToLong(BlockTransactionHashIndex::getValue).sum(); @@ -728,6 +728,11 @@ public class Wallet extends Persistable implements Comparable { transaction.addOutput(payment.getAmount(), payment.getAddress()); } + //Add OP_RETURNs + for(byte[] opReturn : opReturns) { + transaction.addOutput(0L, new Script(List.of(ScriptChunk.fromOpcode(ScriptOpCodes.OP_RETURN), ScriptChunk.fromData(opReturn)))); + } + double noChangeVSize = transaction.getVirtualSize(); long noChangeFeeRequiredAmt = (fee == null ? (long)Math.floor(feeRate * noChangeVSize) : fee); From 99440eda7f8a2b5a8adec68d32a704634157a3d3 Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Tue, 26 Oct 2021 17:35:13 +0200 Subject: [PATCH 072/155] fix high stonewall fee issue, add support for generalized transaction diagram --- .../sparrowwallet/drongo/protocol/Script.java | 8 ++++++ .../sparrowwallet/drongo/wallet/Payment.java | 7 +++++- .../sparrowwallet/drongo/wallet/Wallet.java | 8 ++++-- .../drongo/wallet/WalletTransaction.java | 25 ++++++++++++++++--- 4 files changed, 42 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/sparrowwallet/drongo/protocol/Script.java b/src/main/java/com/sparrowwallet/drongo/protocol/Script.java index 11aa82e..b79025e 100644 --- a/src/main/java/com/sparrowwallet/drongo/protocol/Script.java +++ b/src/main/java/com/sparrowwallet/drongo/protocol/Script.java @@ -165,6 +165,14 @@ public class Script { throw new ProtocolException("Script not a standard form that contains a single hash"); } + public Address getToAddress() { + try { + return getToAddresses()[0]; + } catch(Exception e) { + return null; + } + } + /** * Gets the destination address from this script, if it's in the required form. */ diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/Payment.java b/src/main/java/com/sparrowwallet/drongo/wallet/Payment.java index 1145f97..82e100d 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/Payment.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/Payment.java @@ -7,13 +7,18 @@ public class Payment { private String label; private long amount; private boolean sendMax; - private Type type = Type.DEFAULT; + private Type type; public Payment(Address address, String label, long amount, boolean sendMax) { + this(address, label, amount, sendMax, Type.DEFAULT); + } + + public Payment(Address address, String label, long amount, boolean sendMax, Type type) { this.address = address; this.label = label; this.amount = amount; this.sendMax = sendMax; + this.type = type; } public Address getAddress() { diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java index 35a839e..259348c 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java @@ -518,6 +518,10 @@ public class Wallet extends Persistable implements Comparable { return getWalletTxos().keySet().stream().anyMatch(ref -> ref.getHash().equals(txInput.getOutpoint().getHash()) && ref.getIndex() == txInput.getOutpoint().getIndex()); } + public boolean isWalletTxo(TransactionOutput txOutput) { + return getWalletTxos().keySet().stream().anyMatch(ref -> ref.getHash().equals(txOutput.getHash()) && ref.getIndex() == txOutput.getIndex()); + } + public boolean isWalletTxo(BlockTransactionHashIndex txo) { return getWalletTxos().containsKey(txo); } @@ -771,7 +775,7 @@ public class Wallet extends Persistable implements Comparable { List setChangeAmts = getSetChangeAmounts(selectedUtxoSets, totalPaymentAmount, noChangeFeeRequiredAmt); double noChangeFeeRate = (fee == null ? feeRate : noChangeFeeRequiredAmt / transaction.getVirtualSize()); long costOfChangeAmt = getCostOfChange(noChangeFeeRate, longTermFeeRate); - if(setChangeAmts.stream().allMatch(amt -> amt > costOfChangeAmt)) { + if(setChangeAmts.stream().allMatch(amt -> amt > costOfChangeAmt) || (numSets > 1 && differenceAmt / transaction.getVirtualSize() > noChangeFeeRate * 2)) { //Change output is required, determine new fee once change output has been added WalletNode changeNode = getFreshNode(KeyPurpose.CHANGE); while(txExcludedChangeNodes.contains(changeNode)) { @@ -796,7 +800,7 @@ public class Wallet extends Persistable implements Comparable { if(setChangeAmts.stream().anyMatch(amt -> amt < costOfChangeAmt)) { //The new fee has meant that one of the change outputs is now dust. We pay too high a fee without change, but change is dust when added. - if(numSets > 1) { + if(numSets > 1 && differenceAmt / transaction.getVirtualSize() < noChangeFeeRate * 2) { //Maximize privacy. Pay a higher fee to keep multiple output sets. return new WalletTransaction(this, transaction, utxoSelectors, selectedUtxos, txPayments, differenceAmt); } else { diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/WalletTransaction.java b/src/main/java/com/sparrowwallet/drongo/wallet/WalletTransaction.java index 31c0339..5e86cb8 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/WalletTransaction.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/WalletTransaction.java @@ -1,6 +1,7 @@ package com.sparrowwallet.drongo.wallet; import com.sparrowwallet.drongo.address.Address; +import com.sparrowwallet.drongo.protocol.Sha256Hash; import com.sparrowwallet.drongo.protocol.Transaction; import com.sparrowwallet.drongo.psbt.PSBT; @@ -21,12 +22,17 @@ public class WalletTransaction { private final List payments; private final Map changeMap; private final long fee; + private final Map inputTransactions; public WalletTransaction(Wallet wallet, Transaction transaction, List utxoSelectors, Map selectedUtxos, List payments, long fee) { this(wallet, transaction, utxoSelectors, selectedUtxos, payments, Collections.emptyMap(), fee); } public WalletTransaction(Wallet wallet, Transaction transaction, List utxoSelectors, Map selectedUtxos, List payments, Map changeMap, long fee) { + this(wallet, transaction, utxoSelectors, selectedUtxos, payments, changeMap, fee, Collections.emptyMap()); + } + + public WalletTransaction(Wallet wallet, Transaction transaction, List utxoSelectors, Map selectedUtxos, List payments, Map changeMap, long fee, Map inputTransactions) { this.wallet = wallet; this.transaction = transaction; this.utxoSelectors = utxoSelectors; @@ -34,6 +40,7 @@ public class WalletTransaction { this.payments = payments; this.changeMap = changeMap; this.fee = fee; + this.inputTransactions = inputTransactions; } public PSBT createPSBT() { @@ -80,12 +87,16 @@ public class WalletTransaction { return selectedUtxos.keySet().stream().mapToLong(BlockTransactionHashIndex::getValue).sum(); } + public Map getInputTransactions() { + return inputTransactions; + } + /** * Fee percentage matches the Coldcard implementation of total fee as a percentage of total value out * @return the fee percentage */ public double getFeePercentage() { - return (double)getFee() / (getTotal() - getFee()); + return getFee() == 0 ? 0 : (double)getFee() / (getTotal() - getFee()); } public boolean isCoinControlUsed() { @@ -97,11 +108,19 @@ public class WalletTransaction { } public boolean isPremixSend(Payment payment) { - return isWalletSend(getWallet().getChildWallet(StandardAccount.WHIRLPOOL_PREMIX), payment); + return isWalletSend(StandardAccount.WHIRLPOOL_PREMIX, payment); } public boolean isBadbankSend(Payment payment) { - return isWalletSend(getWallet().getChildWallet(StandardAccount.WHIRLPOOL_BADBANK), payment); + return isWalletSend(StandardAccount.WHIRLPOOL_BADBANK, payment); + } + + private boolean isWalletSend(StandardAccount childAccount, Payment payment) { + if(getWallet() != null) { + return isWalletSend(getWallet().getChildWallet(childAccount), payment); + } + + return false; } public boolean isWalletSend(Wallet wallet, Payment payment) { From 24d9e5fcda84058c48964e2abe21600f61ec359d Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Wed, 27 Oct 2021 12:00:02 +0200 Subject: [PATCH 073/155] walletnode toString refactor --- src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java | 4 ++-- src/main/java/com/sparrowwallet/drongo/wallet/WalletNode.java | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java index 259348c..d2b98b9 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java @@ -1038,7 +1038,7 @@ public class Wallet extends Persistable implements Comparable { for(TransactionInput txInput : signingNodes.keySet()) { WalletNode walletNode = signingNodes.get(txInput); Map keystoreKeysForNode = getKeystores().stream().collect(Collectors.toMap(keystore -> getScriptType().getOutputKey(keystore.getPubKey(walletNode)), Function.identity(), - (u, v) -> { throw new IllegalStateException("Duplicate keys from different keystores for node " + walletNode.getDerivationPath()); }, + (u, v) -> { throw new IllegalStateException("Duplicate keys from different keystores for node " + walletNode); }, LinkedHashMap::new)); Map keySignatureMap = new LinkedHashMap<>(); @@ -1138,7 +1138,7 @@ public class Wallet extends Persistable implements Comparable { for(PSBTInput psbtInput : signingNodes.keySet()) { WalletNode walletNode = signingNodes.get(psbtInput); Map keystoreKeysForNode = getKeystores().stream().collect(Collectors.toMap(keystore -> getScriptType().getOutputKey(keystore.getPubKey(walletNode)), Function.identity(), - (u, v) -> { throw new IllegalStateException("Duplicate keys from different keystores for node " + walletNode.getDerivationPath()); }, + (u, v) -> { throw new IllegalStateException("Duplicate keys from different keystores for node " + walletNode); }, LinkedHashMap::new)); Map keySignatureMap; diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/WalletNode.java b/src/main/java/com/sparrowwallet/drongo/wallet/WalletNode.java index fc699fd..97fbe33 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/WalletNode.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/WalletNode.java @@ -158,7 +158,7 @@ public class WalletNode extends Persistable implements Comparable { @Override public String toString() { - return derivationPath; + return derivationPath.replace("m", ".."); } @Override From 434c18ef0a97d899b534bf81496207542ebbd395 Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Wed, 27 Oct 2021 16:13:32 +0200 Subject: [PATCH 074/155] add wallet label and mixConfig indexRange --- .../com/sparrowwallet/drongo/wallet/MixConfig.java | 14 ++++++++++++-- .../com/sparrowwallet/drongo/wallet/Wallet.java | 9 +++++++++ 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/MixConfig.java b/src/main/java/com/sparrowwallet/drongo/wallet/MixConfig.java index 26062b6..387a626 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/MixConfig.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/MixConfig.java @@ -5,6 +5,7 @@ import java.io.File; public class MixConfig extends Persistable { private String scode; private Boolean mixOnStartup; + private String indexRange; private File mixToWalletFile; private String mixToWalletName; private Integer minMixes; @@ -14,9 +15,10 @@ public class MixConfig extends Persistable { public MixConfig() { } - public MixConfig(String scode, Boolean mixOnStartup, File mixToWalletFile, String mixToWalletName, Integer minMixes, int receiveIndex, int changeIndex) { + public MixConfig(String scode, Boolean mixOnStartup, String indexRange, File mixToWalletFile, String mixToWalletName, Integer minMixes, int receiveIndex, int changeIndex) { this.scode = scode; this.mixOnStartup = mixOnStartup; + this.indexRange = indexRange; this.mixToWalletFile = mixToWalletFile; this.mixToWalletName = mixToWalletName; this.minMixes = minMixes; @@ -40,6 +42,14 @@ public class MixConfig extends Persistable { this.mixOnStartup = mixOnStartup; } + public String getIndexRange() { + return indexRange; + } + + public void setIndexRange(String indexRange) { + this.indexRange = indexRange; + } + public File getMixToWalletFile() { return mixToWalletFile; } @@ -81,6 +91,6 @@ public class MixConfig extends Persistable { } public MixConfig copy() { - return new MixConfig(scode, mixOnStartup, mixToWalletFile, mixToWalletName, minMixes, receiveIndex, changeIndex); + return new MixConfig(scode, mixOnStartup, indexRange, mixToWalletFile, mixToWalletName, minMixes, receiveIndex, changeIndex); } } diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java index d2b98b9..10d892c 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java @@ -27,6 +27,7 @@ public class Wallet extends Persistable implements Comparable { public static final String ALLOW_DERIVATIONS_MATCHING_OTHER_SCRIPT_TYPES_PROPERTY = "com.sparrowwallet.allowDerivationsMatchingOtherScriptTypes"; private String name; + private String label; private Wallet masterWallet; private List childWallets = new ArrayList<>(); private Network network = Network.get(); @@ -196,6 +197,14 @@ public class Wallet extends Persistable implements Comparable { this.name = name; } + public String getLabel() { + return label; + } + + public void setLabel(String label) { + this.label = label; + } + public Network getNetwork() { return network; } From 360550a7183683ad4ee929a4c5411075bd751ffd Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Thu, 28 Oct 2021 13:52:18 +0200 Subject: [PATCH 075/155] fix rounding issue when converting btc values to sats --- src/main/java/com/sparrowwallet/drongo/BitcoinUnit.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/sparrowwallet/drongo/BitcoinUnit.java b/src/main/java/com/sparrowwallet/drongo/BitcoinUnit.java index b067c87..a1e9de7 100644 --- a/src/main/java/com/sparrowwallet/drongo/BitcoinUnit.java +++ b/src/main/java/com/sparrowwallet/drongo/BitcoinUnit.java @@ -17,7 +17,7 @@ public enum BitcoinUnit { BTC("BTC") { @Override public long getSatsValue(double unitValue) { - return (long)(unitValue * Transaction.SATOSHIS_PER_BITCOIN); + return Math.round(unitValue * Transaction.SATOSHIS_PER_BITCOIN); } @Override From bdb9900d8d94f62b8714e14e151635813c7c258d Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Fri, 29 Oct 2021 13:21:53 +0200 Subject: [PATCH 076/155] improve multi account wallet name display --- src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java index 10d892c..596bf1b 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java @@ -75,6 +75,14 @@ public class Wallet extends Persistable implements Comparable { return getMasterWallet().getName() + "-" + name; } + public String getFullDisplayName() { + if(isMasterWallet()) { + return name; + } + + return getMasterWallet().getName() + " - " + name; + } + public String getMasterName() { if(isMasterWallet()) { return name; From 6c03c4106ae612c0b80370c3ed5495b1ba9225bc Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Fri, 29 Oct 2021 14:33:15 +0200 Subject: [PATCH 077/155] respect wallet labels when displaying name --- .../com/sparrowwallet/drongo/wallet/Wallet.java | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java index 596bf1b..4703745 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java @@ -69,18 +69,27 @@ public class Wallet extends Persistable implements Comparable { public String getFullName() { if(isMasterWallet()) { - return name; + return childWallets.isEmpty() ? name : name + "-" + (label != null && !label.isEmpty() ? label : getAutomaticName()); } - return getMasterWallet().getName() + "-" + name; + return getMasterWallet().getName() + "-" + getDisplayName(this); } public String getFullDisplayName() { if(isMasterWallet()) { - return name; + return childWallets.isEmpty() ? name : name + " - " + (label != null && !label.isEmpty() ? label : getAutomaticName()); } - return getMasterWallet().getName() + " - " + name; + return getMasterWallet().getName() + " - " + getDisplayName(this); + } + + private String getDisplayName(Wallet wallet) { + return wallet.label != null && !wallet.label.isEmpty() ? wallet.label : wallet.name; + } + + public String getAutomaticName() { + int account = getAccountIndex(); + return (account < 0 || account > 9) ? getName() : (!isWhirlpoolMasterWallet() || account > 1 ? "Account #" + account : "Deposit"); } public String getMasterName() { From f46d6277551cdb69286fbc3a6e536e0542cb7170 Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Wed, 10 Nov 2021 15:43:11 +0200 Subject: [PATCH 078/155] allow zero length paths when parsing psbt key derivations --- src/main/java/com/sparrowwallet/drongo/psbt/PSBTEntry.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/sparrowwallet/drongo/psbt/PSBTEntry.java b/src/main/java/com/sparrowwallet/drongo/psbt/PSBTEntry.java index b505475..cf7575b 100644 --- a/src/main/java/com/sparrowwallet/drongo/psbt/PSBTEntry.java +++ b/src/main/java/com/sparrowwallet/drongo/psbt/PSBTEntry.java @@ -64,7 +64,7 @@ public class PSBTEntry { throw new PSBTParseException("Invalid master fingerprint specified: " + masterFingerprint); } if(data.length < 8) { - throw new PSBTParseException("Invalid key derivation specified: not enough bytes"); + return new KeyDerivation(masterFingerprint, "m"); } List bip32pathList = readBIP32Derivation(Arrays.copyOfRange(data, 4, data.length)); String bip32path = KeyDerivation.writePath(bip32pathList); From ebf7128ae5737c3ae4f9b54ad0df72b9bfa63594 Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Fri, 12 Nov 2021 15:54:22 +0200 Subject: [PATCH 079/155] support utxo sets in wallet tx --- .../sparrowwallet/drongo/wallet/Wallet.java | 6 ++-- .../drongo/wallet/WalletTransaction.java | 31 ++++++++++++------- 2 files changed, 22 insertions(+), 15 deletions(-) diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java index 4703745..07514c3 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java @@ -828,7 +828,7 @@ public class Wallet extends Persistable implements Comparable { //The new fee has meant that one of the change outputs is now dust. We pay too high a fee without change, but change is dust when added. if(numSets > 1 && differenceAmt / transaction.getVirtualSize() < noChangeFeeRate * 2) { //Maximize privacy. Pay a higher fee to keep multiple output sets. - return new WalletTransaction(this, transaction, utxoSelectors, selectedUtxos, txPayments, differenceAmt); + return new WalletTransaction(this, transaction, utxoSelectors, selectedUtxoSets, txPayments, differenceAmt); } else { //Maxmize efficiency. Increase value required from inputs and try again. valueRequiredAmt = totalSelectedAmt + 1; @@ -836,10 +836,10 @@ public class Wallet extends Persistable implements Comparable { } } - return new WalletTransaction(this, transaction, utxoSelectors, selectedUtxos, txPayments, changeMap, changeFeeRequiredAmt); + return new WalletTransaction(this, transaction, utxoSelectors, selectedUtxoSets, txPayments, changeMap, changeFeeRequiredAmt); } - return new WalletTransaction(this, transaction, utxoSelectors, selectedUtxos, txPayments, differenceAmt); + return new WalletTransaction(this, transaction, utxoSelectors, selectedUtxoSets, txPayments, differenceAmt); } } diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/WalletTransaction.java b/src/main/java/com/sparrowwallet/drongo/wallet/WalletTransaction.java index 5e86cb8..ce23c0b 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/WalletTransaction.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/WalletTransaction.java @@ -5,10 +5,7 @@ import com.sparrowwallet.drongo.protocol.Sha256Hash; import com.sparrowwallet.drongo.protocol.Transaction; import com.sparrowwallet.drongo.psbt.PSBT; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Map; +import java.util.*; /** * WalletTransaction contains a draft transaction along with associated metadata. The draft transaction has empty signatures but is otherwise complete. @@ -18,25 +15,25 @@ public class WalletTransaction { private final Wallet wallet; private final Transaction transaction; private final List utxoSelectors; - private final Map selectedUtxos; + private final List> selectedUtxoSets; private final List payments; private final Map changeMap; private final long fee; private final Map inputTransactions; - public WalletTransaction(Wallet wallet, Transaction transaction, List utxoSelectors, Map selectedUtxos, List payments, long fee) { - this(wallet, transaction, utxoSelectors, selectedUtxos, payments, Collections.emptyMap(), fee); + public WalletTransaction(Wallet wallet, Transaction transaction, List utxoSelectors, List> selectedUtxoSets, List payments, long fee) { + this(wallet, transaction, utxoSelectors, selectedUtxoSets, payments, Collections.emptyMap(), fee); } - public WalletTransaction(Wallet wallet, Transaction transaction, List utxoSelectors, Map selectedUtxos, List payments, Map changeMap, long fee) { - this(wallet, transaction, utxoSelectors, selectedUtxos, payments, changeMap, fee, Collections.emptyMap()); + public WalletTransaction(Wallet wallet, Transaction transaction, List utxoSelectors, List> selectedUtxoSets, List payments, Map changeMap, long fee) { + this(wallet, transaction, utxoSelectors, selectedUtxoSets, payments, changeMap, fee, Collections.emptyMap()); } - public WalletTransaction(Wallet wallet, Transaction transaction, List utxoSelectors, Map selectedUtxos, List payments, Map changeMap, long fee, Map inputTransactions) { + public WalletTransaction(Wallet wallet, Transaction transaction, List utxoSelectors, List> selectedUtxoSets, List payments, Map changeMap, long fee, Map inputTransactions) { this.wallet = wallet; this.transaction = transaction; this.utxoSelectors = utxoSelectors; - this.selectedUtxos = selectedUtxos; + this.selectedUtxoSets = selectedUtxoSets; this.payments = payments; this.changeMap = changeMap; this.fee = fee; @@ -60,9 +57,19 @@ public class WalletTransaction { } public Map getSelectedUtxos() { + if(selectedUtxoSets.size() == 1) { + return selectedUtxoSets.get(0); + } + + Map selectedUtxos = new LinkedHashMap<>(); + selectedUtxoSets.forEach(selectedUtxos::putAll); return selectedUtxos; } + public List> getSelectedUtxoSets() { + return selectedUtxoSets; + } + public List getPayments() { return payments; } @@ -84,7 +91,7 @@ public class WalletTransaction { } public long getTotal() { - return selectedUtxos.keySet().stream().mapToLong(BlockTransactionHashIndex::getValue).sum(); + return getSelectedUtxos().keySet().stream().mapToLong(BlockTransactionHashIndex::getValue).sum(); } public Map getInputTransactions() { From 8e4924783224fc894b45855cdbd866981413db3b Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Sat, 13 Nov 2021 15:04:37 +0200 Subject: [PATCH 080/155] introduce multipath derivations to output descriptors and use h for hardened indexes --- .../sparrowwallet/drongo/KeyDerivation.java | 14 +++--- .../drongo/OutputDescriptor.java | 43 ++++++++++++++++--- .../drongo/crypto/ChildNumber.java | 6 ++- 3 files changed, 50 insertions(+), 13 deletions(-) diff --git a/src/main/java/com/sparrowwallet/drongo/KeyDerivation.java b/src/main/java/com/sparrowwallet/drongo/KeyDerivation.java index b1f4e10..2f811ec 100644 --- a/src/main/java/com/sparrowwallet/drongo/KeyDerivation.java +++ b/src/main/java/com/sparrowwallet/drongo/KeyDerivation.java @@ -68,13 +68,17 @@ public class KeyDerivation { } public static String writePath(List pathList) { - String path = "m"; - for (ChildNumber child: pathList) { - path += "/"; - path += child.toString(); + return writePath(pathList, true); + } + + public static String writePath(List pathList, boolean useApostrophes) { + StringBuilder path = new StringBuilder("m"); + for(ChildNumber child: pathList) { + path.append("/"); + path.append(child.toString(useApostrophes)); } - return path; + return path.toString(); } public static boolean isValid(String derivationPath) { diff --git a/src/main/java/com/sparrowwallet/drongo/OutputDescriptor.java b/src/main/java/com/sparrowwallet/drongo/OutputDescriptor.java index 0e8bfd9..e5ac381 100644 --- a/src/main/java/com/sparrowwallet/drongo/OutputDescriptor.java +++ b/src/main/java/com/sparrowwallet/drongo/OutputDescriptor.java @@ -22,10 +22,11 @@ public class OutputDescriptor { private static final String INPUT_CHARSET = "0123456789()[],'/*abcdefgh@:$%{}IJKLMNOPQRSTUVWXYZ&+-.;<=>?!^_|~ijklmnopqrstuvwxyzABCDEFGH`#\"\\ "; private static final String CHECKSUM_CHARSET = "qpzry9x8gf2tvdw0s3jn54khce6mua7l"; - private static final Pattern XPUB_PATTERN = Pattern.compile("(\\[[^\\]]+\\])?(.pub[^/\\,)]{100,112})(/[/\\d*'hH]+)?"); + private static final Pattern XPUB_PATTERN = Pattern.compile("(\\[[^\\]]+\\])?(.pub[^/\\,)]{100,112})(/[/\\d*'hH<>;]+)?"); private static final Pattern PUBKEY_PATTERN = Pattern.compile("(\\[[^\\]]+\\])?(0[23][0-9a-fA-F]{32})"); private static final Pattern MULTI_PATTERN = Pattern.compile("multi\\(([\\d+])"); private static final Pattern KEY_ORIGIN_PATTERN = Pattern.compile("\\[([A-Fa-f0-9]{8})([/\\d'hH]+)\\]"); + private static final Pattern MULTIPATH_PATTERN = Pattern.compile("<([\\d*'hH;]+)>"); private static final Pattern CHECKSUM_PATTERN = Pattern.compile("#([" + CHECKSUM_CHARSET + "]{8})$"); private final ScriptType scriptType; @@ -258,12 +259,25 @@ public class OutputDescriptor { } public static OutputDescriptor getOutputDescriptor(Wallet wallet, KeyPurpose keyPurpose, Integer index) { + return getOutputDescriptor(wallet, keyPurpose == null ? null : List.of(keyPurpose), index); + } + + public static OutputDescriptor getOutputDescriptor(Wallet wallet, List keyPurposes, Integer index) { Map extendedKeyDerivationMap = new LinkedHashMap<>(); Map extendedKeyChildDerivationMap = new LinkedHashMap<>(); for(Keystore keystore : wallet.getKeystores()) { extendedKeyDerivationMap.put(keystore.getExtendedPublicKey(), keystore.getKeyDerivation()); - if(keyPurpose != null) { - extendedKeyChildDerivationMap.put(keystore.getExtendedPublicKey(), keyPurpose.getPathIndex().num() + "/" + (index == null ? "*" : index)); + if(keyPurposes != null) { + String chain; + if(keyPurposes.size() == 1) { + chain = Integer.toString(keyPurposes.get(0).getPathIndex().num()); + } else { + StringJoiner joiner = new StringJoiner(";"); + keyPurposes.forEach(keyPurpose -> joiner.add(Integer.toString(keyPurpose.getPathIndex().num()))); + chain = "<" + joiner + ">"; + } + + extendedKeyChildDerivationMap.put(keystore.getExtendedPublicKey(), chain + "/" + (index == null ? "*" : index)); } } @@ -395,7 +409,7 @@ public class OutputDescriptor { private static BigInteger polyMod(BigInteger c, int val) { byte c0 = c.shiftRight(35).byteValue(); - c = c.and(new BigInteger("7ffffffff", 16)).shiftLeft(5).or(BigInteger.valueOf(val)); + c = c.and(new BigInteger("7ffffffff", 16)).shiftLeft(5).xor(BigInteger.valueOf(val)); if((c0 & 1) > 0) { c = c.xor(new BigInteger("f5dee51989", 16)); @@ -461,10 +475,10 @@ public class OutputDescriptor { Utils.LexicographicByteArrayComparator lexicographicByteArrayComparator = new Utils.LexicographicByteArrayComparator(); sortedKeys.sort((o1, o2) -> { - List derivation1 = KeyDerivation.parsePath(mapChildrenDerivations.get(o1)); + List derivation1 = getDerivations(mapChildrenDerivations.get(o1)).get(0); derivation1.add(0, o1.getKeyChildNumber()); ECKey key1 = o1.getKey(derivation1); - List derivation2 = KeyDerivation.parsePath(mapChildrenDerivations.get(o2)); + List derivation2 = getDerivations(mapChildrenDerivations.get(o2)).get(0); derivation2.add(0, o2.getKeyChildNumber()); ECKey key2 = o2.getKey(derivation2); return lexicographicByteArrayComparator.compare(key1.getPubKey(), key2.getPubKey()); @@ -473,6 +487,21 @@ public class OutputDescriptor { return sortedKeys; } + private List> getDerivations(String childDerivation) { + Matcher matcher = MULTIPATH_PATTERN.matcher(childDerivation); + if(matcher.find()) { + String multipath = matcher.group(1); + String[] paths = multipath.split(";"); + List> derivations = new ArrayList<>(); + for(String path : paths) { + derivations.add(KeyDerivation.parsePath(childDerivation.replace(matcher.group(), path))); + } + return derivations; + } else { + return List.of(KeyDerivation.parsePath(childDerivation)); + } + } + private String toString(ExtendedKey pubKey, boolean addKeyOrigin) { StringBuilder keyBuilder = new StringBuilder(); KeyDerivation keyDerivation = extendedPublicKeys.get(pubKey); @@ -482,7 +511,7 @@ public class OutputDescriptor { keyBuilder.append(keyDerivation.getMasterFingerprint()); keyBuilder.append("/"); } - keyBuilder.append(keyDerivation.getDerivationPath().replaceFirst("^m?/", "")); + keyBuilder.append(keyDerivation.getDerivationPath().replaceFirst("^m?/", "").replace('\'', 'h')); keyBuilder.append("]"); } diff --git a/src/main/java/com/sparrowwallet/drongo/crypto/ChildNumber.java b/src/main/java/com/sparrowwallet/drongo/crypto/ChildNumber.java index 67ec957..0f83fbb 100644 --- a/src/main/java/com/sparrowwallet/drongo/crypto/ChildNumber.java +++ b/src/main/java/com/sparrowwallet/drongo/crypto/ChildNumber.java @@ -46,7 +46,11 @@ public class ChildNumber { public int i() { return i; } public String toString() { - return String.format(Locale.US, "%d%s", num(), isHardened() ? "'" : ""); + return toString(true); + } + + public String toString(boolean useApostrophes) { + return String.format(Locale.US, "%d%s", num(), isHardened() ? (useApostrophes ? "'" : "h") : ""); } public boolean equals(Object o) { From 3a061cb73ae318fcbe7ea1dcb0b670e78803d9fa Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Wed, 17 Nov 2021 14:49:22 +0200 Subject: [PATCH 081/155] remove taproot activation code, update libsecp256k1 libs --- .../drongo/protocol/ScriptType.java | 6 +----- .../java/org/bitcoin/Secp256k1Context.java | 2 +- .../native/linux/x64/libsecp256k1.so | Bin 244824 -> 243168 bytes .../native/osx/x64/libsecp256k1.dylib | Bin 446176 -> 387832 bytes 4 files changed, 2 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/sparrowwallet/drongo/protocol/ScriptType.java b/src/main/java/com/sparrowwallet/drongo/protocol/ScriptType.java index cf849cf..ecbec90 100644 --- a/src/main/java/com/sparrowwallet/drongo/protocol/ScriptType.java +++ b/src/main/java/com/sparrowwallet/drongo/protocol/ScriptType.java @@ -1134,14 +1134,10 @@ public enum ScriptType { @Override public List getAllowedPolicyTypes() { - return (Network.get() == Network.MAINNET && LocalDate.now().isAfter(TAPROOT_MAINNET_ACTIVATION_DATE) || (System.getProperty(Network.BLOCK_HEIGHT_PROPERTY) != null && Integer.parseInt(System.getProperty(Network.BLOCK_HEIGHT_PROPERTY)) >= 709632)) - || Network.get() == Network.TESTNET || Network.get() == Network.REGTEST || Network.get() == Network.SIGNET ? List.of(SINGLE) : Collections.emptyList(); + return List.of(SINGLE); } }; - //To avoid relying solely on a network-dependent block height >= 709632 check, use a approximate activation date. This can be removed once Taproot has activated on mainnet. - private static final LocalDate TAPROOT_MAINNET_ACTIVATION_DATE = LocalDate.of(2021, Month.NOVEMBER, 17); - private final String name; private final String description; private final String defaultDerivationPath; diff --git a/src/main/java/org/bitcoin/Secp256k1Context.java b/src/main/java/org/bitcoin/Secp256k1Context.java index 5034987..2e8909e 100644 --- a/src/main/java/org/bitcoin/Secp256k1Context.java +++ b/src/main/java/org/bitcoin/Secp256k1Context.java @@ -45,7 +45,7 @@ public class Secp256k1Context { return true; } catch(IOException e) { - log.debug("Error loading libsecp256k1 library", e); + log.error("Error loading libsecp256k1 library", e); } return false; diff --git a/src/main/resources/native/linux/x64/libsecp256k1.so b/src/main/resources/native/linux/x64/libsecp256k1.so index ce37197bae4bd06b932f63a171495a36a76b5c86..cbeadb7b173fe18dd025c8b500ceac298310921a 100755 GIT binary patch delta 68723 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�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 delta 74869 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
  • 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 Wn>CI*mhKHXzO#1*yn>aD^uGaxey<|{ literal 446176 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 u*@O%yx2x3db-@taC#}$>~G=)wm@O|0tl9=SX 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¥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 z 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
    $Ln5gPB|4M`*0_RMg0#pO%j|bSVQ$n--Ctc*G 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 IwNSJF1Ll$iqW}N^ From 4a4a62f239f5de1e25e927ee9996326383ea7f89 Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Thu, 25 Nov 2021 16:13:57 +0200 Subject: [PATCH 082/155] various changes to support soroban --- src/main/java/com/sparrowwallet/drongo/Drongo.java | 6 ++++++ src/main/java/com/sparrowwallet/drongo/psbt/PSBT.java | 8 -------- .../java/com/sparrowwallet/drongo/wallet/Payment.java | 2 +- src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java | 8 ++++++++ 4 files changed, 15 insertions(+), 9 deletions(-) diff --git a/src/main/java/com/sparrowwallet/drongo/Drongo.java b/src/main/java/com/sparrowwallet/drongo/Drongo.java index 6d77694..24eb887 100644 --- a/src/main/java/com/sparrowwallet/drongo/Drongo.java +++ b/src/main/java/com/sparrowwallet/drongo/Drongo.java @@ -1,6 +1,7 @@ package com.sparrowwallet.drongo; import com.sparrowwallet.drongo.rpc.BitcoinJSONRPCClient; +import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.slf4j.event.Level; @@ -8,6 +9,7 @@ import org.zeromq.SocketType; import org.zeromq.ZContext; import org.zeromq.ZMQ; +import java.security.Provider; import java.util.List; import java.util.Map; import java.util.concurrent.ExecutorService; @@ -80,4 +82,8 @@ public class Drongo { ch.qos.logback.classic.Logger root = (ch.qos.logback.classic.Logger)LoggerFactory.getLogger(org.slf4j.Logger.ROOT_LOGGER_NAME); root.setLevel(ch.qos.logback.classic.Level.toLevel(level.toString())); } + + public static Provider getProvider() { + return new BouncyCastleProvider(); + } } diff --git a/src/main/java/com/sparrowwallet/drongo/psbt/PSBT.java b/src/main/java/com/sparrowwallet/drongo/psbt/PSBT.java index e26caae..e77a165 100644 --- a/src/main/java/com/sparrowwallet/drongo/psbt/PSBT.java +++ b/src/main/java/com/sparrowwallet/drongo/psbt/PSBT.java @@ -257,14 +257,6 @@ public class PSBT { if(transaction == null) { throw new PSBTParseException("Missing transaction"); } - - if(currentState == STATE_INPUTS) { - throw new PSBTParseException("Missing inputs"); - } - - if(currentState == STATE_OUTPUTS) { - throw new PSBTParseException("Missing outputs"); - } } if(log.isDebugEnabled()) { diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/Payment.java b/src/main/java/com/sparrowwallet/drongo/wallet/Payment.java index 82e100d..2d0c428 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/Payment.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/Payment.java @@ -62,6 +62,6 @@ public class Payment { } public enum Type { - DEFAULT, WHIRLPOOL_FEE, FAKE_MIX; + DEFAULT, WHIRLPOOL_FEE, FAKE_MIX, MIX; } } diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java index 07514c3..97c9787 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java @@ -164,6 +164,14 @@ public class Wallet extends Persistable implements Comparable { return null; } + public List getAllWallets() { + List allWallets = new ArrayList<>(); + Wallet masterWallet = isMasterWallet() ? this : getMasterWallet(); + allWallets.add(masterWallet); + allWallets.addAll(masterWallet.getChildWallets()); + return allWallets; + } + public StandardAccount getStandardAccountType() { int accountIndex = getAccountIndex(); return Arrays.stream(StandardAccount.values()).filter(standardAccount -> standardAccount.getChildNumber().num() == accountIndex).findFirst().orElse(null); From da14a9bf34945713494cfbef86f8f44aedbc727f Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Fri, 26 Nov 2021 14:04:46 +0200 Subject: [PATCH 083/155] add retrieval of wallet nodes and history --- src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java index 97c9787..4a9633c 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java @@ -509,6 +509,13 @@ public class Wallet extends Persistable implements Comparable { } } + public Map> getWalletNodes() { + Map> walletNodes = new LinkedHashMap<>(); + getNode(KeyPurpose.RECEIVE).getChildren().forEach(childNode -> walletNodes.put(childNode, childNode.getTransactionOutputs())); + getNode(KeyPurpose.CHANGE).getChildren().forEach(childNode -> walletNodes.put(childNode, childNode.getTransactionOutputs())); + return walletNodes; + } + public boolean isWalletAddress(Address address) { return getWalletAddresses().containsKey(address); } From 16d348a91d4e7583d4a79a89188bfb68ac806be1 Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Mon, 29 Nov 2021 15:30:31 +0200 Subject: [PATCH 084/155] add support for dumped private keys --- .../com/sparrowwallet/drongo/Network.java | 16 ++- .../drongo/crypto/DumpedPrivateKey.java | 88 ++++++++++++++ .../crypto/VersionedChecksummedBytes.java | 109 ++++++++++++++++++ 3 files changed, 208 insertions(+), 5 deletions(-) create mode 100644 src/main/java/com/sparrowwallet/drongo/crypto/DumpedPrivateKey.java create mode 100644 src/main/java/com/sparrowwallet/drongo/crypto/VersionedChecksummedBytes.java diff --git a/src/main/java/com/sparrowwallet/drongo/Network.java b/src/main/java/com/sparrowwallet/drongo/Network.java index de3782a..646de38 100644 --- a/src/main/java/com/sparrowwallet/drongo/Network.java +++ b/src/main/java/com/sparrowwallet/drongo/Network.java @@ -1,14 +1,14 @@ package com.sparrowwallet.drongo; public enum Network { - MAINNET("mainnet", 0, "1", 5, "3", "bc", ExtendedKey.Header.xprv, ExtendedKey.Header.xpub, 8332), - TESTNET("testnet", 111, "mn", 196, "2", "tb", ExtendedKey.Header.tprv, ExtendedKey.Header.tpub, 18332), - REGTEST("regtest", 111, "mn", 196, "2", "bcrt", ExtendedKey.Header.tprv, ExtendedKey.Header.tpub, 18443), - SIGNET("signet", 111, "mn", 196, "2", "tb", ExtendedKey.Header.tprv, ExtendedKey.Header.tpub, 38332); + MAINNET("mainnet", 0, "1", 5, "3", "bc", ExtendedKey.Header.xprv, ExtendedKey.Header.xpub, 128, 8332), + TESTNET("testnet", 111, "mn", 196, "2", "tb", ExtendedKey.Header.tprv, ExtendedKey.Header.tpub, 239, 18332), + REGTEST("regtest", 111, "mn", 196, "2", "bcrt", ExtendedKey.Header.tprv, ExtendedKey.Header.tpub, 239, 18443), + SIGNET("signet", 111, "mn", 196, "2", "tb", ExtendedKey.Header.tprv, ExtendedKey.Header.tpub, 239, 38332); public static final String BLOCK_HEIGHT_PROPERTY = "com.sparrowwallet.blockHeight"; - Network(String name, int p2pkhAddressHeader, String p2pkhAddressPrefix, int p2shAddressHeader, String p2shAddressPrefix, String bech32AddressHrp, ExtendedKey.Header xprvHeader, ExtendedKey.Header xpubHeader, int defaultPort) { + Network(String name, int p2pkhAddressHeader, String p2pkhAddressPrefix, int p2shAddressHeader, String p2shAddressPrefix, String bech32AddressHrp, ExtendedKey.Header xprvHeader, ExtendedKey.Header xpubHeader, int dumpedPrivateKeyHeader, int defaultPort) { this.name = name; this.p2pkhAddressHeader = p2pkhAddressHeader; this.p2pkhAddressPrefix = p2pkhAddressPrefix; @@ -17,6 +17,7 @@ public enum Network { this.bech32AddressHrp = bech32AddressHrp; this.xprvHeader = xprvHeader; this.xpubHeader = xpubHeader; + this.dumpedPrivateKeyHeader = dumpedPrivateKeyHeader; this.defaultPort = defaultPort; } @@ -28,6 +29,7 @@ public enum Network { private final String bech32AddressHrp; private final ExtendedKey.Header xprvHeader; private final ExtendedKey.Header xpubHeader; + private final int dumpedPrivateKeyHeader; private final int defaultPort; private static Network currentNetwork; @@ -56,6 +58,10 @@ public enum Network { return xpubHeader; } + public int getDumpedPrivateKeyHeader() { + return dumpedPrivateKeyHeader; + } + public int getDefaultPort() { return defaultPort; } diff --git a/src/main/java/com/sparrowwallet/drongo/crypto/DumpedPrivateKey.java b/src/main/java/com/sparrowwallet/drongo/crypto/DumpedPrivateKey.java new file mode 100644 index 0000000..52abd86 --- /dev/null +++ b/src/main/java/com/sparrowwallet/drongo/crypto/DumpedPrivateKey.java @@ -0,0 +1,88 @@ +package com.sparrowwallet.drongo.crypto; + + +import com.sparrowwallet.drongo.Network; + +import java.util.Arrays; +import java.util.Objects; + +/** + * Parses and generates private keys in the form used by the Bitcoin "dumpprivkey" command. This is the private key + * bytes with a header byte and 4 checksum bytes at the end. If there are 33 private key bytes instead of 32, then + * the last byte is a discriminator value for the compressed pubkey. + */ +public class DumpedPrivateKey extends VersionedChecksummedBytes { + private final boolean compressed; + + /** + * Construct a private key from its Base58 representation. + * @param base58 + * The textual form of the private key. + */ + public static DumpedPrivateKey fromBase58(String base58) { + return new DumpedPrivateKey(base58); + } + + // Used by ECKey.getPrivateKeyEncoded() + DumpedPrivateKey(byte[] keyBytes, boolean compressed) { + super(Network.get().getDumpedPrivateKeyHeader(), encode(keyBytes, compressed)); + this.compressed = compressed; + } + + private static byte[] encode(byte[] keyBytes, boolean compressed) { + if(keyBytes.length != 32) { + throw new IllegalArgumentException("Private keys must be 32 bytes"); + } + + if (!compressed) { + return keyBytes; + } else { + // Keys that have compressed public components have an extra 1 byte on the end in dumped form. + byte[] bytes = new byte[33]; + System.arraycopy(keyBytes, 0, bytes, 0, 32); + bytes[32] = 1; + return bytes; + } + } + + private DumpedPrivateKey(String encoded) { + super(encoded); + if(version != Network.get().getDumpedPrivateKeyHeader()) + throw new IllegalArgumentException("Invalid version " + version + " for network " + Network.get()); + if(bytes.length == 33 && bytes[32] == 1) { + compressed = true; + bytes = Arrays.copyOf(bytes, 32); // Chop off the additional marker byte. + } else if(bytes.length == 32) { + compressed = false; + } else { + throw new IllegalArgumentException("Wrong number of bytes for a private key, not 32 or 33"); + } + } + + /** + * Returns an ECKey created from this encoded private key. + */ + public ECKey getKey() { + return ECKey.fromPrivate(bytes); + } + + @Override + public boolean equals(Object o) { + if(this == o) { + return true; + } + if(o == null || getClass() != o.getClass()) { + return false; + } + if(!super.equals(o)) { + return false; + } + DumpedPrivateKey that = (DumpedPrivateKey) o; + return compressed == that.compressed; + } + + @Override + public int hashCode() { + return Objects.hash(super.hashCode(), compressed); + } +} \ No newline at end of file diff --git a/src/main/java/com/sparrowwallet/drongo/crypto/VersionedChecksummedBytes.java b/src/main/java/com/sparrowwallet/drongo/crypto/VersionedChecksummedBytes.java new file mode 100644 index 0000000..56f280f --- /dev/null +++ b/src/main/java/com/sparrowwallet/drongo/crypto/VersionedChecksummedBytes.java @@ -0,0 +1,109 @@ +package com.sparrowwallet.drongo.crypto; + + +import com.sparrowwallet.drongo.Utils; +import com.sparrowwallet.drongo.protocol.Base58; +import com.sparrowwallet.drongo.protocol.Sha256Hash; + +import java.io.Serializable; +import java.util.Arrays; +import java.util.Objects; + +/** + *

    In Bitcoin the following format is often used to represent some type of key:

    + *

    + *

    [one version byte] [data bytes] [4 checksum bytes]
    + *

    + *

    and the result is then Base58 encoded. This format is used for addresses, and private keys exported using the + * dumpprivkey command.

    + */ +public class VersionedChecksummedBytes implements Serializable, Cloneable, Comparable { + protected final int version; + protected byte[] bytes; + + protected VersionedChecksummedBytes(String encoded) { + byte[] versionAndDataBytes = Base58.decodeChecked(encoded); + byte versionByte = versionAndDataBytes[0]; + version = versionByte & 0xFF; + bytes = new byte[versionAndDataBytes.length - 1]; + System.arraycopy(versionAndDataBytes, 1, bytes, 0, versionAndDataBytes.length - 1); + } + + protected VersionedChecksummedBytes(int version, byte[] bytes) { + this.version = version; + this.bytes = bytes; + } + + /** + * Returns the base-58 encoded String representation of this + * object, including version and checksum bytes. + */ + public final String toBase58() { + // A stringified buffer is: + // 1 byte version + data bytes + 4 bytes check code (a truncated hash) + byte[] addressBytes = new byte[1 + bytes.length + 4]; + addressBytes[0] = (byte) version; + System.arraycopy(bytes, 0, addressBytes, 1, bytes.length); + byte[] checksum = Sha256Hash.hashTwice(addressBytes, 0, bytes.length + 1); + System.arraycopy(checksum, 0, addressBytes, bytes.length + 1, 4); + return Base58.encode(addressBytes); + } + + @Override + public String toString() { + return toBase58(); + } + + @Override + public boolean equals(Object o) { + if(this == o) { + return true; + } + if(o == null || getClass() != o.getClass()) { + return false; + } + VersionedChecksummedBytes that = (VersionedChecksummedBytes) o; + return version == that.version && Arrays.equals(bytes, that.bytes); + } + + @Override + public int hashCode() { + int result = Objects.hash(version); + result = 31 * result + Arrays.hashCode(bytes); + return result; + } + + /** + * {@inheritDoc} + * + * This implementation narrows the return type to VersionedChecksummedBytes + * and allows subclasses to throw CloneNotSupportedException even though it + * is never thrown by this implementation. + */ + @Override + public VersionedChecksummedBytes clone() throws CloneNotSupportedException { + return (VersionedChecksummedBytes) super.clone(); + } + + /** + * {@inheritDoc} + * + * This implementation uses an optimized Google Guava method to compare bytes. + */ + @Override + public int compareTo(VersionedChecksummedBytes o) { + int result = Integer.compare(this.version, o.version); + Utils.LexicographicByteArrayComparator lexicographicByteArrayComparator = new Utils.LexicographicByteArrayComparator(); + return result != 0 ? result : lexicographicByteArrayComparator.compare(this.bytes, o.bytes); + } + + /** + * Returns the "version" or "header" byte: the first byte of the data. This is used to disambiguate what the + * contents apply to, for example, which network the key or address is valid on. + * + * @return A positive number between 0 and 255. + */ + public int getVersion() { + return version; + } +} From 20ec0f95fb187ebb94cba8c9265eba38c23ef8ea Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Wed, 1 Dec 2021 14:13:58 +0200 Subject: [PATCH 085/155] test for two person coinjoin --- .../com/sparrowwallet/drongo/wallet/WalletTransaction.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/WalletTransaction.java b/src/main/java/com/sparrowwallet/drongo/wallet/WalletTransaction.java index ce23c0b..f224e3e 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/WalletTransaction.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/WalletTransaction.java @@ -110,6 +110,10 @@ public class WalletTransaction { return !utxoSelectors.isEmpty() && utxoSelectors.get(0) instanceof PresetUtxoSelector; } + public boolean isTwoPersonCoinjoin() { + return !utxoSelectors.isEmpty() && utxoSelectors.get(0) instanceof StonewallUtxoSelector; + } + public boolean isConsolidationSend(Payment payment) { return isWalletSend(getWallet(), payment); } From 3131b265a5c9c18d33af4ee67b273ab4df1bf4a1 Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Mon, 13 Dec 2021 15:42:02 +0200 Subject: [PATCH 086/155] ensure selected utxo sets retain stable ordering --- src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java index 4a9633c..232c79a 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java @@ -932,7 +932,7 @@ public class Wallet extends Persistable implements Comparable { Map utxos = getWalletUtxos(includeSpentMempoolOutputs); for(Collection selectedInputs : selectedInputSets) { total += selectedInputs.stream().mapToLong(BlockTransactionHashIndex::getValue).sum(); - Map selectedInputsMap = new HashMap<>(utxos); + Map selectedInputsMap = new TreeMap<>(utxos); selectedInputsMap.keySet().retainAll(selectedInputs); selectedInputSetsList.add(selectedInputsMap); } From 60e989b946cbfa86f7121671a986788c17fbaa34 Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Mon, 13 Dec 2021 16:02:20 +0200 Subject: [PATCH 087/155] follow up --- src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java index 232c79a..f098e0b 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java @@ -733,7 +733,7 @@ public class Wallet extends Persistable implements Comparable { while(true) { List> selectedUtxoSets = selectInputSets(utxoSelectors, utxoFilters, valueRequiredAmt, feeRate, longTermFeeRate, groupByAddress, includeMempoolOutputs, includeSpentMempoolOutputs, sendMax); - Map selectedUtxos = new HashMap<>(); + Map selectedUtxos = new LinkedHashMap<>(); selectedUtxoSets.forEach(selectedUtxos::putAll); long totalSelectedAmt = selectedUtxos.keySet().stream().mapToLong(BlockTransactionHashIndex::getValue).sum(); int numSets = selectedUtxoSets.size(); From 6ac593f161f7d17bf1f99658a92d7d65d25997be Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Tue, 14 Dec 2021 11:20:45 +0200 Subject: [PATCH 088/155] detect if output descriptor represents a cosigner --- .../java/com/sparrowwallet/drongo/OutputDescriptor.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/sparrowwallet/drongo/OutputDescriptor.java b/src/main/java/com/sparrowwallet/drongo/OutputDescriptor.java index e5ac381..cb4dc66 100644 --- a/src/main/java/com/sparrowwallet/drongo/OutputDescriptor.java +++ b/src/main/java/com/sparrowwallet/drongo/OutputDescriptor.java @@ -132,6 +132,10 @@ public class OutputDescriptor { return extendedPublicKeys.size() > 1; } + public boolean isCosigner() { + return !isMultisig() && scriptType.isAllowed(PolicyType.MULTI); + } + public ExtendedKey getSingletonExtendedPublicKey() { if(isMultisig()) { throw new IllegalStateException("Output descriptor contains multiple public keys but singleton requested"); @@ -233,7 +237,7 @@ public class OutputDescriptor { public Wallet toWallet() { Wallet wallet = new Wallet(); - wallet.setPolicyType(isMultisig() ? PolicyType.MULTI : PolicyType.SINGLE); + wallet.setPolicyType(isMultisig() || isCosigner() ? PolicyType.MULTI : PolicyType.SINGLE); wallet.setScriptType(scriptType); for(Map.Entry extKeyEntry : extendedPublicKeys.entrySet()) { @@ -469,7 +473,7 @@ public class OutputDescriptor { private List sortExtendedPubKeys(Collection keys) { List sortedKeys = new ArrayList<>(keys); - if(mapChildrenDerivations == null || mapChildrenDerivations.isEmpty()) { + if(mapChildrenDerivations == null || mapChildrenDerivations.isEmpty() || mapChildrenDerivations.containsKey(null)) { return sortedKeys; } From 8ac3f4738038245c0235bed145e1669d8f655980 Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Wed, 15 Dec 2021 10:10:55 +0200 Subject: [PATCH 089/155] shuffle utxos within input sets --- src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java index f098e0b..607177f 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java @@ -932,8 +932,12 @@ public class Wallet extends Persistable implements Comparable { Map utxos = getWalletUtxos(includeSpentMempoolOutputs); for(Collection selectedInputs : selectedInputSets) { total += selectedInputs.stream().mapToLong(BlockTransactionHashIndex::getValue).sum(); - Map selectedInputsMap = new TreeMap<>(utxos); - selectedInputsMap.keySet().retainAll(selectedInputs); + Map selectedInputsMap = new LinkedHashMap<>(); + List shuffledInputs = new ArrayList<>(selectedInputs); + Collections.shuffle(shuffledInputs); + for(BlockTransactionHashIndex shuffledInput : shuffledInputs) { + selectedInputsMap.put(shuffledInput, utxos.get(shuffledInput)); + } selectedInputSetsList.add(selectedInputsMap); } From d59da365065fffe07fbaf6bae45b457752114e79 Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Wed, 15 Dec 2021 14:13:29 +0200 Subject: [PATCH 090/155] return zero total when some input values are not available --- .../sparrowwallet/drongo/wallet/WalletTransaction.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/WalletTransaction.java b/src/main/java/com/sparrowwallet/drongo/wallet/WalletTransaction.java index f224e3e..36b0282 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/WalletTransaction.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/WalletTransaction.java @@ -91,7 +91,11 @@ public class WalletTransaction { } public long getTotal() { - return getSelectedUtxos().keySet().stream().mapToLong(BlockTransactionHashIndex::getValue).sum(); + return inputAmountsValid() ? getSelectedUtxos().keySet().stream().mapToLong(BlockTransactionHashIndex::getValue).sum() : 0; + } + + private boolean inputAmountsValid() { + return getSelectedUtxos().keySet().stream().allMatch(ref -> ref.getValue() > 0); } public Map getInputTransactions() { @@ -103,7 +107,7 @@ public class WalletTransaction { * @return the fee percentage */ public double getFeePercentage() { - return getFee() == 0 ? 0 : (double)getFee() / (getTotal() - getFee()); + return getFee() <= 0 || getTotal() <= 0 ? 0 : (double)getFee() / (getTotal() - getFee()); } public boolean isCoinControlUsed() { From 645be6a5a5a7b434ea9a3991ae85e0b8b6d4f50b Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Thu, 16 Dec 2021 08:28:01 +0200 Subject: [PATCH 091/155] upgrade to logback 1.2.8 --- build.gradle | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/build.gradle b/build.gradle index 8781284..a6ec8ac 100644 --- a/build.gradle +++ b/build.gradle @@ -48,7 +48,7 @@ dependencies { exclude group: 'org.hamcrest', module: 'hamcrest-core' exclude group: 'junit', module: 'junit' } - implementation ('ch.qos.logback:logback-classic:1.2.3') { + implementation ('ch.qos.logback:logback-classic:1.2.8') { exclude group: 'org.hamcrest', module: 'hamcrest-core' exclude group: 'org.slf4j' } @@ -90,12 +90,12 @@ shadowJar { } extraJavaModuleInfo { - module('logback-core-1.2.3.jar', 'logback.core', '1.2.3') { + module('logback-core-1.2.8.jar', 'logback.core', '1.2.8') { exports('ch.qos.logback.core') exports('ch.qos.logback.core.spi') requires('java.xml') } - module('logback-classic-1.2.3.jar', 'logback.classic', '1.2.3') { + module('logback-classic-1.2.8.jar', 'logback.classic', '1.2.8') { exports('ch.qos.logback.classic') exports('ch.qos.logback.classic.spi') requires('org.slf4j') From c1f6a1245e4632deb19af64faaa6ffaaca475313 Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Thu, 16 Dec 2021 10:06:06 +0200 Subject: [PATCH 092/155] add seed tool wallet model --- .../java/com/sparrowwallet/drongo/wallet/WalletModel.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/WalletModel.java b/src/main/java/com/sparrowwallet/drongo/wallet/WalletModel.java index afd24b1..fa74ccf 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/WalletModel.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/WalletModel.java @@ -1,7 +1,7 @@ package com.sparrowwallet.drongo.wallet; public enum WalletModel { - SEED, SPARROW, BITCOIN_CORE, ELECTRUM, TREZOR_1, TREZOR_T, COLDCARD, LEDGER_NANO_S, LEDGER_NANO_X, DIGITALBITBOX_01, KEEPKEY, SPECTER_DESKTOP, COBO_VAULT, BITBOX_02, SPECTER_DIY, PASSPORT, BLUE_WALLET, KEYSTONE, SEEDSIGNER, CARAVAN; + SEED, SPARROW, BITCOIN_CORE, ELECTRUM, TREZOR_1, TREZOR_T, COLDCARD, LEDGER_NANO_S, LEDGER_NANO_X, DIGITALBITBOX_01, KEEPKEY, SPECTER_DESKTOP, COBO_VAULT, BITBOX_02, SPECTER_DIY, PASSPORT, BLUE_WALLET, KEYSTONE, SEEDSIGNER, CARAVAN, SEED_TOOL; public static WalletModel getModel(String model) { return valueOf(model.toUpperCase()); @@ -40,11 +40,15 @@ public enum WalletModel { return "bluewallet"; } + if(this == SEED_TOOL) { + return "seedtool"; + } + return this.toString().toLowerCase(); } public boolean alwaysIncludeNonWitnessUtxo() { - if(this == COLDCARD || this == COBO_VAULT || this == PASSPORT || this == KEYSTONE) { + if(this == COLDCARD || this == COBO_VAULT || this == PASSPORT || this == KEYSTONE || this == SEED_TOOL) { return false; } From 083288061ffe6e08805bb58108a9afab0d93fb0f Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Tue, 4 Jan 2022 10:33:47 +0200 Subject: [PATCH 093/155] rename gordian seed tool, support retrieving a keystore from an output descriptor more generally --- .../com/sparrowwallet/drongo/Network.java | 4 ++++ .../drongo/OutputDescriptor.java | 21 +++++++++++++++++++ .../drongo/wallet/WalletModel.java | 6 +++--- 3 files changed, 28 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/sparrowwallet/drongo/Network.java b/src/main/java/com/sparrowwallet/drongo/Network.java index 646de38..4175ac5 100644 --- a/src/main/java/com/sparrowwallet/drongo/Network.java +++ b/src/main/java/com/sparrowwallet/drongo/Network.java @@ -38,6 +38,10 @@ public enum Network { return name; } + public String toDisplayString() { + return name.substring(0, 1).toUpperCase() + name.substring(1); + } + public int getP2PKHAddressHeader() { return p2pkhAddressHeader; } diff --git a/src/main/java/com/sparrowwallet/drongo/OutputDescriptor.java b/src/main/java/com/sparrowwallet/drongo/OutputDescriptor.java index cb4dc66..2e3f416 100644 --- a/src/main/java/com/sparrowwallet/drongo/OutputDescriptor.java +++ b/src/main/java/com/sparrowwallet/drongo/OutputDescriptor.java @@ -254,6 +254,27 @@ public class OutputDescriptor { return wallet; } + public Wallet toKeystoreWallet(String masterFingerprint) { + Wallet wallet = new Wallet(); + if(isMultisig()) { + throw new IllegalStateException("Multisig output descriptors are unsupported."); + } + + ExtendedKey extendedKey = getSingletonExtendedPublicKey(); + if(masterFingerprint == null) { + masterFingerprint = getKeyDerivation(extendedKey).getMasterFingerprint(); + } + + wallet.setScriptType(getScriptType()); + Keystore keystore = new Keystore(); + keystore.setKeyDerivation(new KeyDerivation(masterFingerprint, KeyDerivation.writePath(getKeyDerivation(extendedKey).getDerivation()))); + keystore.setExtendedPublicKey(extendedKey); + wallet.getKeystores().add(keystore); + wallet.setDefaultPolicy(Policy.getPolicy(isCosigner() ? PolicyType.MULTI : PolicyType.SINGLE, wallet.getScriptType(), wallet.getKeystores(), 1)); + + return wallet; + } + public static OutputDescriptor getOutputDescriptor(Wallet wallet) { return getOutputDescriptor(wallet, null); } diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/WalletModel.java b/src/main/java/com/sparrowwallet/drongo/wallet/WalletModel.java index fa74ccf..e9b5379 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/WalletModel.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/WalletModel.java @@ -1,7 +1,7 @@ package com.sparrowwallet.drongo.wallet; public enum WalletModel { - SEED, SPARROW, BITCOIN_CORE, ELECTRUM, TREZOR_1, TREZOR_T, COLDCARD, LEDGER_NANO_S, LEDGER_NANO_X, DIGITALBITBOX_01, KEEPKEY, SPECTER_DESKTOP, COBO_VAULT, BITBOX_02, SPECTER_DIY, PASSPORT, BLUE_WALLET, KEYSTONE, SEEDSIGNER, CARAVAN, SEED_TOOL; + SEED, SPARROW, BITCOIN_CORE, ELECTRUM, TREZOR_1, TREZOR_T, COLDCARD, LEDGER_NANO_S, LEDGER_NANO_X, DIGITALBITBOX_01, KEEPKEY, SPECTER_DESKTOP, COBO_VAULT, BITBOX_02, SPECTER_DIY, PASSPORT, BLUE_WALLET, KEYSTONE, SEEDSIGNER, CARAVAN, GORDIAN_SEED_TOOL; public static WalletModel getModel(String model) { return valueOf(model.toUpperCase()); @@ -40,7 +40,7 @@ public enum WalletModel { return "bluewallet"; } - if(this == SEED_TOOL) { + if(this == GORDIAN_SEED_TOOL) { return "seedtool"; } @@ -48,7 +48,7 @@ public enum WalletModel { } public boolean alwaysIncludeNonWitnessUtxo() { - if(this == COLDCARD || this == COBO_VAULT || this == PASSPORT || this == KEYSTONE || this == SEED_TOOL) { + if(this == COLDCARD || this == COBO_VAULT || this == PASSPORT || this == KEYSTONE || this == GORDIAN_SEED_TOOL) { return false; } From 3a557e3af8bd17abf7697f93e586baf67745b460 Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Sun, 9 Jan 2022 11:05:17 +0200 Subject: [PATCH 094/155] introduce general purpose hash index record --- build.gradle | 4 +-- .../drongo/protocol/HashIndex.java | 3 ++ .../drongo/wallet/BlockTransaction.java | 28 ++----------------- 3 files changed, 7 insertions(+), 28 deletions(-) create mode 100644 src/main/java/com/sparrowwallet/drongo/protocol/HashIndex.java diff --git a/build.gradle b/build.gradle index a6ec8ac..9345192 100644 --- a/build.gradle +++ b/build.gradle @@ -26,8 +26,8 @@ if(os.macOsX) { osName = "osx" } -sourceCompatibility = 11 -targetCompatibility = 11 +sourceCompatibility = 16 +targetCompatibility = 16 repositories { mavenCentral() diff --git a/src/main/java/com/sparrowwallet/drongo/protocol/HashIndex.java b/src/main/java/com/sparrowwallet/drongo/protocol/HashIndex.java new file mode 100644 index 0000000..b192c4d --- /dev/null +++ b/src/main/java/com/sparrowwallet/drongo/protocol/HashIndex.java @@ -0,0 +1,3 @@ +package com.sparrowwallet.drongo.protocol; + +public record HashIndex(Sha256Hash hash, long index) {} diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/BlockTransaction.java b/src/main/java/com/sparrowwallet/drongo/wallet/BlockTransaction.java index ea2d122..31b1c50 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/BlockTransaction.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/BlockTransaction.java @@ -1,12 +1,12 @@ package com.sparrowwallet.drongo.wallet; +import com.sparrowwallet.drongo.protocol.HashIndex; import com.sparrowwallet.drongo.protocol.Sha256Hash; import com.sparrowwallet.drongo.protocol.Transaction; import java.util.Collections; import java.util.Date; import java.util.List; -import java.util.Objects; import java.util.stream.Collectors; public class BlockTransaction extends BlockTransactionHash implements Comparable { @@ -67,7 +67,7 @@ public class BlockTransaction extends BlockTransactionHash implements Comparable } return blockchainTransaction.getTransaction().getInputs().stream() - .map(txInput -> new HashIndex(txInput.getOutpoint().getHash(), (int)txInput.getOutpoint().getIndex())) + .map(txInput -> new HashIndex(txInput.getOutpoint().getHash(), txInput.getOutpoint().getIndex())) .collect(Collectors.toList()); } @@ -80,28 +80,4 @@ public class BlockTransaction extends BlockTransactionHash implements Comparable .map(txOutput -> new HashIndex(blockchainTransaction.getHash(), txOutput.getIndex())) .collect(Collectors.toList()); } - - private static class HashIndex { - public Sha256Hash hash; - public int index; - - public HashIndex(Sha256Hash hash, int index) { - this.hash = hash; - this.index = index; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - HashIndex hashIndex = (HashIndex) o; - return index == hashIndex.index && - hash.equals(hashIndex.hash); - } - - @Override - public int hashCode() { - return Objects.hash(hash, index); - } - } } From 34bd72d87aac7286fd0ca7e94f5a931f00d13cb4 Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Wed, 12 Jan 2022 15:42:44 +0200 Subject: [PATCH 095/155] get wif from eckey --- .../java/com/sparrowwallet/drongo/crypto/ECKey.java | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/main/java/com/sparrowwallet/drongo/crypto/ECKey.java b/src/main/java/com/sparrowwallet/drongo/crypto/ECKey.java index 17f19cb..be966e0 100644 --- a/src/main/java/com/sparrowwallet/drongo/crypto/ECKey.java +++ b/src/main/java/com/sparrowwallet/drongo/crypto/ECKey.java @@ -326,6 +326,17 @@ public class ECKey { return priv; } + /** + * Exports the private key in the form used by Bitcoin Core's "dumpprivkey" and "importprivkey" commands. Use + * the {@link DumpedPrivateKey#toString()} method to get the string. + * + * @return Private key bytes as a {@link DumpedPrivateKey}. + * @throws IllegalStateException if the private key is not available. + */ + public DumpedPrivateKey getPrivateKeyEncoded() { + return new DumpedPrivateKey(getPrivKeyBytes(), isCompressed()); + } + /** * Returns whether this key is using the compressed form or not. Compressed pubkeys are only 33 bytes, not 64. */ From 8dca2ee3f0ba8dbebf88c3629b2a52c7eecf5b89 Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Wed, 19 Jan 2022 13:48:20 +0200 Subject: [PATCH 096/155] add wallet watchLast field --- .../java/com/sparrowwallet/drongo/wallet/Wallet.java | 10 ++++++++++ .../com/sparrowwallet/drongo/wallet/WalletNode.java | 4 ++++ 2 files changed, 14 insertions(+) diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java index 607177f..8c07f9c 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java @@ -41,6 +41,7 @@ public class Wallet extends Persistable implements Comparable { private final Map utxoMixes = new HashMap<>(); private Integer storedBlockHeight; private Integer gapLimit; + private Integer watchLast; private Date birthDate; public Wallet() { @@ -339,6 +340,14 @@ public class Wallet extends Persistable implements Comparable { this.gapLimit = gapLimit; } + public Integer getWatchLast() { + return watchLast; + } + + public void setWatchLast(Integer watchLast) { + this.watchLast = watchLast; + } + public Date getBirthDate() { return birthDate; } @@ -1463,6 +1472,7 @@ public class Wallet extends Persistable implements Comparable { } copy.setStoredBlockHeight(getStoredBlockHeight()); copy.gapLimit = gapLimit; + copy.watchLast = watchLast; copy.birthDate = birthDate; return copy; diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/WalletNode.java b/src/main/java/com/sparrowwallet/drongo/wallet/WalletNode.java index 97fbe33..7012b5b 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/WalletNode.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/WalletNode.java @@ -94,6 +94,10 @@ public class WalletNode extends Persistable implements Comparable { this.children = children; } + public boolean isUsed() { + return !transactionOutputs.isEmpty(); + } + public Set getTransactionOutputs() { return transactionOutputs; } From fe61c633ae230c3425d52a0c9ac6264ea77e5041 Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Thu, 20 Jan 2022 17:12:00 +0200 Subject: [PATCH 097/155] performance optimisations --- .../drongo/crypto/ChildNumber.java | 2 +- .../drongo/protocol/HashIndex.java | 47 ++++++++++++++++- .../drongo/wallet/BlockTransaction.java | 52 +++++++++---------- .../drongo/wallet/WalletNode.java | 2 +- 4 files changed, 73 insertions(+), 30 deletions(-) diff --git a/src/main/java/com/sparrowwallet/drongo/crypto/ChildNumber.java b/src/main/java/com/sparrowwallet/drongo/crypto/ChildNumber.java index 0f83fbb..90d591c 100644 --- a/src/main/java/com/sparrowwallet/drongo/crypto/ChildNumber.java +++ b/src/main/java/com/sparrowwallet/drongo/crypto/ChildNumber.java @@ -50,7 +50,7 @@ public class ChildNumber { } public String toString(boolean useApostrophes) { - return String.format(Locale.US, "%d%s", num(), isHardened() ? (useApostrophes ? "'" : "h") : ""); + return num() + (isHardened() ? (useApostrophes ? "'" : "h") : ""); } public boolean equals(Object o) { diff --git a/src/main/java/com/sparrowwallet/drongo/protocol/HashIndex.java b/src/main/java/com/sparrowwallet/drongo/protocol/HashIndex.java index b192c4d..2559099 100644 --- a/src/main/java/com/sparrowwallet/drongo/protocol/HashIndex.java +++ b/src/main/java/com/sparrowwallet/drongo/protocol/HashIndex.java @@ -1,3 +1,48 @@ package com.sparrowwallet.drongo.protocol; -public record HashIndex(Sha256Hash hash, long index) {} +public class HashIndex { + private final Sha256Hash hash; + private final long index; + + public HashIndex(Sha256Hash hash, long index) { + this.hash = hash; + this.index = index; + } + + public Sha256Hash getHash() { + return hash; + } + + public long getIndex() { + return index; + } + + @Override + public String toString() { + return hash.toString() + ":" + index; + } + + @Override + public boolean equals(Object o) { + if(this == o) { + return true; + } + if(o == null || getClass() != o.getClass()) { + return false; + } + + HashIndex hashIndex = (HashIndex) o; + + if(index != hashIndex.index) { + return false; + } + return hash.equals(hashIndex.hash); + } + + @Override + public int hashCode() { + int result = hash.hashCode(); + result = 31 * result + (int) (index ^ (index >>> 32)); + return result; + } +} diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/BlockTransaction.java b/src/main/java/com/sparrowwallet/drongo/wallet/BlockTransaction.java index 31b1c50..dec93b9 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/BlockTransaction.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/BlockTransaction.java @@ -1,18 +1,19 @@ package com.sparrowwallet.drongo.wallet; -import com.sparrowwallet.drongo.protocol.HashIndex; -import com.sparrowwallet.drongo.protocol.Sha256Hash; -import com.sparrowwallet.drongo.protocol.Transaction; +import com.sparrowwallet.drongo.protocol.*; import java.util.Collections; import java.util.Date; -import java.util.List; -import java.util.stream.Collectors; +import java.util.HashSet; +import java.util.Set; public class BlockTransaction extends BlockTransactionHash implements Comparable { private final Transaction transaction; private final Sha256Hash blockHash; + private final Set spending = new HashSet<>(); + private final Set funding = new HashSet<>(); + public BlockTransaction(Sha256Hash hash, int height, Date date, Long fee, Transaction transaction) { this(hash, height, date, fee, transaction, null); } @@ -25,6 +26,15 @@ public class BlockTransaction extends BlockTransactionHash implements Comparable super(hash, height, date, fee, label); this.transaction = transaction; this.blockHash = blockHash; + + if(transaction != null) { + for(TransactionInput txInput : transaction.getInputs()) { + spending.add(new HashIndex(txInput.getOutpoint().getHash(), txInput.getOutpoint().getIndex())); + } + for(TransactionOutput txOutput : transaction.getOutputs()) { + funding.add(new HashIndex(hash, txOutput.getIndex())); + } + } } public Transaction getTransaction() { @@ -35,6 +45,14 @@ public class BlockTransaction extends BlockTransactionHash implements Comparable return blockHash; } + public Set getSpending() { + return Collections.unmodifiableSet(spending); + } + + public Set getFunding() { + return Collections.unmodifiableSet(funding); + } + @Override public int compareTo(BlockTransaction blkTx) { int blockOrder = compareBlockOrder(blkTx); @@ -50,34 +68,14 @@ public class BlockTransaction extends BlockTransactionHash implements Comparable return getComparisonHeight() - blkTx.getComparisonHeight(); } - if(getReferencedOutpoints(this).removeAll(getOutputs(blkTx))) { + if(!Collections.disjoint(spending, blkTx.funding)) { return 1; } - if(getReferencedOutpoints(blkTx).removeAll(getOutputs(this))) { + if(!Collections.disjoint(blkTx.spending, funding)) { return -1; } return 0; } - - private static List getReferencedOutpoints(BlockTransaction blockchainTransaction) { - if(blockchainTransaction.getTransaction() == null) { - return Collections.emptyList(); - } - - return blockchainTransaction.getTransaction().getInputs().stream() - .map(txInput -> new HashIndex(txInput.getOutpoint().getHash(), txInput.getOutpoint().getIndex())) - .collect(Collectors.toList()); - } - - private static List getOutputs(BlockTransaction blockchainTransaction) { - if(blockchainTransaction.getTransaction() == null) { - return Collections.emptyList(); - } - - return blockchainTransaction.getTransaction().getOutputs().stream() - .map(txOutput -> new HashIndex(blockchainTransaction.getHash(), txOutput.getIndex())) - .collect(Collectors.toList()); - } } diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/WalletNode.java b/src/main/java/com/sparrowwallet/drongo/wallet/WalletNode.java index 7012b5b..d1fbc9d 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/WalletNode.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/WalletNode.java @@ -175,7 +175,7 @@ public class WalletNode extends Persistable implements Comparable { @Override public int hashCode() { - return Objects.hash(derivationPath); + return derivationPath.hashCode(); } @Override From 61317f15ac795ef1a40c120d1e8aae2b2735c6ec Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Tue, 25 Jan 2022 13:46:02 +0100 Subject: [PATCH 098/155] more nuanced wallet compare with master wallets first --- .../sparrowwallet/drongo/wallet/Wallet.java | 26 ++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java index 8c07f9c..a26f43a 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java @@ -1534,11 +1534,31 @@ public class Wallet extends Persistable implements Comparable { @Override public int compareTo(Wallet other) { - if(getStandardAccountType() != null && other.getStandardAccountType() != null) { - return getStandardAccountType().ordinal() - other.getStandardAccountType().ordinal(); + if(isMasterWallet() && !other.isMasterWallet()) { + return -1; } - return getAccountIndex() - other.getAccountIndex(); + if(!isMasterWallet() && other.isMasterWallet()) { + return 1; + } + + if(getStandardAccountType() != null && other.getStandardAccountType() != null) { + int standardAccountDiff = getStandardAccountType().ordinal() - other.getStandardAccountType().ordinal(); + if(standardAccountDiff != 0) { + return standardAccountDiff; + } + } + + int accountIndexDiff = getAccountIndex() - other.getAccountIndex(); + if(accountIndexDiff != 0) { + return accountIndexDiff; + } + + if(name != null && other.name != null) { + return name.compareTo(other.name); + } + + return 0; } @Override From 9618c73c50e59035cd373d932970f446032cd9e5 Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Mon, 31 Jan 2022 19:12:36 +0200 Subject: [PATCH 099/155] allow short wallet display name retrieval --- src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java index a26f43a..06f5c8e 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java @@ -73,7 +73,7 @@ public class Wallet extends Persistable implements Comparable { return childWallets.isEmpty() ? name : name + "-" + (label != null && !label.isEmpty() ? label : getAutomaticName()); } - return getMasterWallet().getName() + "-" + getDisplayName(this); + return getMasterWallet().getName() + "-" + getDisplayName(); } public String getFullDisplayName() { @@ -81,11 +81,11 @@ public class Wallet extends Persistable implements Comparable { return childWallets.isEmpty() ? name : name + " - " + (label != null && !label.isEmpty() ? label : getAutomaticName()); } - return getMasterWallet().getName() + " - " + getDisplayName(this); + return getMasterWallet().getName() + " - " + getDisplayName(); } - private String getDisplayName(Wallet wallet) { - return wallet.label != null && !wallet.label.isEmpty() ? wallet.label : wallet.name; + public String getDisplayName() { + return label != null && !label.isEmpty() ? label : (isMasterWallet() ? getAutomaticName() : name); } public String getAutomaticName() { From ee732fb2235fbe242d75366fc37d3f53e2082519 Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Thu, 3 Feb 2022 12:43:14 +0200 Subject: [PATCH 100/155] handle wif format private keys with uncompressed pubkeys --- .../java/com/sparrowwallet/drongo/crypto/DumpedPrivateKey.java | 2 +- .../com/sparrowwallet/drongo/protocol/TransactionSignature.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/sparrowwallet/drongo/crypto/DumpedPrivateKey.java b/src/main/java/com/sparrowwallet/drongo/crypto/DumpedPrivateKey.java index 52abd86..8fac3ce 100644 --- a/src/main/java/com/sparrowwallet/drongo/crypto/DumpedPrivateKey.java +++ b/src/main/java/com/sparrowwallet/drongo/crypto/DumpedPrivateKey.java @@ -63,7 +63,7 @@ public class DumpedPrivateKey extends VersionedChecksummedBytes { * Returns an ECKey created from this encoded private key. */ public ECKey getKey() { - return ECKey.fromPrivate(bytes); + return ECKey.fromPrivate(bytes, compressed); } @Override diff --git a/src/main/java/com/sparrowwallet/drongo/protocol/TransactionSignature.java b/src/main/java/com/sparrowwallet/drongo/protocol/TransactionSignature.java index 0ac8613..b15f722 100644 --- a/src/main/java/com/sparrowwallet/drongo/protocol/TransactionSignature.java +++ b/src/main/java/com/sparrowwallet/drongo/protocol/TransactionSignature.java @@ -99,7 +99,7 @@ public class TransactionSignature { } public static TransactionSignature decodeFromBitcoin(byte[] bytes, boolean requireCanonicalEncoding) throws SignatureDecodeException { - if(bytes.length == 64 || bytes.length == 65) { + if(bytes.length == 64) { return decodeFromBitcoin(Type.SCHNORR, bytes, requireCanonicalEncoding); } From de87ab1102db12cad8bbfe814a1346078cf957a5 Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Wed, 9 Feb 2022 11:38:23 +0200 Subject: [PATCH 101/155] add detached labels map to store labels during a wallet refresh --- .../sparrowwallet/drongo/wallet/Wallet.java | 59 +++++++++++++++++-- .../drongo/wallet/WalletNode.java | 36 ++++++++++- 2 files changed, 87 insertions(+), 8 deletions(-) diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java index 06f5c8e..5b19bff 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java @@ -37,6 +37,7 @@ public class Wallet extends Persistable implements Comparable { private List keystores = new ArrayList<>(); private final TreeSet purposeNodes = new TreeSet<>(); private final Map transactions = new HashMap<>(); + private final Map detachedLabels = new HashMap<>(); private MixConfig mixConfig; private final Map utxoMixes = new HashMap<>(); private Integer storedBlockHeight; @@ -116,6 +117,7 @@ public class Wallet extends Persistable implements Comparable { childWallet.setName(standardAccount.getName()); childWallet.purposeNodes.clear(); childWallet.transactions.clear(); + childWallet.detachedLabels.clear(); childWallet.storedBlockHeight = null; childWallet.gapLimit = standardAccount.getMinimumGapLimit(); childWallet.birthDate = null; @@ -273,8 +275,17 @@ public class Wallet extends Persistable implements Comparable { public synchronized void updateTransactions(Map updatedTransactions) { for(BlockTransaction blockTx : updatedTransactions.values()) { - Optional optionalLabel = transactions.values().stream().filter(oldBlTx -> oldBlTx.getHash().equals(blockTx.getHash())).map(BlockTransaction::getLabel).filter(Objects::nonNull).findFirst(); - optionalLabel.ifPresent(blockTx::setLabel); + if(!transactions.isEmpty()) { + Optional optionalLabel = transactions.values().stream().filter(oldBlTx -> oldBlTx.getHash().equals(blockTx.getHash())).map(BlockTransaction::getLabel).filter(Objects::nonNull).findFirst(); + optionalLabel.ifPresent(blockTx::setLabel); + } + + if(!detachedLabels.isEmpty()) { + String label = detachedLabels.remove(blockTx.getHashAsString()); + if(label != null && (blockTx.getLabel() == null || blockTx.getLabel().isEmpty())) { + blockTx.setLabel(label); + } + } } transactions.putAll(updatedTransactions); @@ -284,6 +295,10 @@ public class Wallet extends Persistable implements Comparable { } } + public Map getDetachedLabels() { + return detachedLabels; + } + public MixConfig getMixConfig() { return mixConfig; } @@ -394,7 +409,7 @@ public class Wallet extends Persistable implements Comparable { purposeNode = optionalPurposeNode.get(); } - purposeNode.fillToIndex(getLookAheadIndex(purposeNode)); + purposeNode.fillToIndex(this, getLookAheadIndex(purposeNode)); return purposeNode; } @@ -426,7 +441,7 @@ public class Wallet extends Persistable implements Comparable { } if(index >= node.getChildren().size()) { - node.fillToIndex(index); + node.fillToIndex(this, index); } for(WalletNode childNode : node.getChildren()) { @@ -1311,13 +1326,15 @@ public class Wallet extends Persistable implements Comparable { return BitcoinUnit.SATOSHIS; } - public void clearNodes() { + public void clearNodes(Wallet previousWallet) { + detachedLabels.putAll(previousWallet.getDetachedLabels(true)); purposeNodes.clear(); transactions.clear(); storedBlockHeight = 0; } public void clearHistory() { + detachedLabels.putAll(getDetachedLabels(false)); for(WalletNode purposeNode : purposeNodes) { purposeNode.clearHistory(); } @@ -1326,6 +1343,35 @@ public class Wallet extends Persistable implements Comparable { storedBlockHeight = 0; } + private Map getDetachedLabels(boolean includeAddresses) { + Map labels = new HashMap<>(); + for(BlockTransaction blockTransaction : transactions.values()) { + if(blockTransaction.getLabel() != null && !blockTransaction.getLabel().isEmpty()) { + labels.put(blockTransaction.getHashAsString(), blockTransaction.getLabel()); + } + } + + for(WalletNode purposeNode : purposeNodes) { + for(WalletNode addressNode : purposeNode.getChildren()) { + if(includeAddresses && addressNode.getLabel() != null && !addressNode.getLabel().isEmpty()) { + labels.put(getAddress(addressNode).toString(), addressNode.getLabel()); + } + + for(BlockTransactionHashIndex output : addressNode.getTransactionOutputs()) { + if(output.getLabel() != null && !output.getLabel().isEmpty()) { + labels.put(output.getHash().toString() + "<" + output.getIndex(), output.getLabel()); + } + + if(output.isSpent() && output.getSpentBy().getLabel() != null && !output.getSpentBy().getLabel().isEmpty()) { + labels.put(output.getSpentBy().getHash() + ">" + output.getSpentBy().getIndex(), output.getSpentBy().getLabel()); + } + } + } + } + + return labels; + } + public boolean isValid() { try { checkWallet(); @@ -1466,6 +1512,9 @@ public class Wallet extends Persistable implements Comparable { for(Sha256Hash hash : transactions.keySet()) { copy.transactions.put(hash, transactions.get(hash)); } + for(String entry : detachedLabels.keySet()) { + copy.detachedLabels.put(entry, detachedLabels.get(entry)); + } copy.setMixConfig(mixConfig == null ? null : mixConfig.copy()); for(Sha256Hash hash : utxoMixes.keySet()) { copy.utxoMixes.put(hash, utxoMixes.get(hash)); diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/WalletNode.java b/src/main/java/com/sparrowwallet/drongo/wallet/WalletNode.java index d1fbc9d..6fabedd 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/WalletNode.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/WalletNode.java @@ -106,10 +106,26 @@ public class WalletNode extends Persistable implements Comparable { this.transactionOutputs = transactionOutputs; } - public synchronized void updateTransactionOutputs(Set updatedOutputs) { + public synchronized void updateTransactionOutputs(Wallet wallet, Set updatedOutputs) { for(BlockTransactionHashIndex txo : updatedOutputs) { - Optional optionalLabel = transactionOutputs.stream().filter(oldTxo -> oldTxo.getHash().equals(txo.getHash()) && oldTxo.getIndex() == txo.getIndex()).map(BlockTransactionHash::getLabel).filter(Objects::nonNull).findFirst(); - optionalLabel.ifPresent(txo::setLabel); + if(!transactionOutputs.isEmpty()) { + Optional optionalLabel = transactionOutputs.stream().filter(oldTxo -> oldTxo.getHash().equals(txo.getHash()) && oldTxo.getIndex() == txo.getIndex()).map(BlockTransactionHash::getLabel).filter(Objects::nonNull).findFirst(); + optionalLabel.ifPresent(txo::setLabel); + } + + if(!wallet.getDetachedLabels().isEmpty()) { + String label = wallet.getDetachedLabels().remove(txo.getHash().toString() + "<" + txo.getIndex()); + if(label != null && (txo.getLabel() == null || txo.getLabel().isEmpty())) { + txo.setLabel(label); + } + + if(txo.isSpent()) { + String spentByLabel = wallet.getDetachedLabels().remove(txo.getSpentBy().getHash() + ">" + txo.getSpentBy().getIndex()); + if(spentByLabel != null && (txo.getSpentBy().getLabel() == null || txo.getSpentBy().getLabel().isEmpty())) { + txo.getSpentBy().setLabel(spentByLabel); + } + } + } } transactionOutputs.clear(); @@ -134,6 +150,20 @@ public class WalletNode extends Persistable implements Comparable { return value; } + public Set fillToIndex(Wallet wallet, int index) { + Set newNodes = fillToIndex(index); + if(!wallet.getDetachedLabels().isEmpty()) { + for(WalletNode newNode : newNodes) { + String label = wallet.getDetachedLabels().remove(wallet.getAddress(newNode).toString()); + if(label != null && (newNode.getLabel() == null || newNode.getLabel().isEmpty())) { + newNode.setLabel(label); + } + } + } + + return newNodes; + } + public synchronized Set fillToIndex(int index) { Set newNodes = new TreeSet<>(); for(int i = 0; i <= index; i++) { From 78359961f369f4f8b016973529241048f2ef216d Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Wed, 9 Feb 2022 13:23:37 +0200 Subject: [PATCH 102/155] followup --- src/main/java/com/sparrowwallet/drongo/wallet/WalletNode.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/WalletNode.java b/src/main/java/com/sparrowwallet/drongo/wallet/WalletNode.java index 6fabedd..27676fa 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/WalletNode.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/WalletNode.java @@ -152,7 +152,7 @@ public class WalletNode extends Persistable implements Comparable { public Set fillToIndex(Wallet wallet, int index) { Set newNodes = fillToIndex(index); - if(!wallet.getDetachedLabels().isEmpty()) { + if(!wallet.getDetachedLabels().isEmpty() && wallet.isValid()) { for(WalletNode newNode : newNodes) { String label = wallet.getDetachedLabels().remove(wallet.getAddress(newNode).toString()); if(label != null && (newNode.getLabel() == null || newNode.getLabel().isEmpty())) { From f73cabad3c76c1eb28b4f02b17c9beb608ba2aa4 Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Wed, 9 Feb 2022 16:07:26 +0200 Subject: [PATCH 103/155] remove unused copy labels method --- .../drongo/wallet/WalletNode.java | 37 ------------------- 1 file changed, 37 deletions(-) diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/WalletNode.java b/src/main/java/com/sparrowwallet/drongo/wallet/WalletNode.java index 27676fa..2394116 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/WalletNode.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/WalletNode.java @@ -248,43 +248,6 @@ public class WalletNode extends Persistable implements Comparable { return copy; } - public boolean copyLabels(WalletNode pastNode) { - if(pastNode == null) { - return false; - } - - boolean changed = false; - - if(label == null && pastNode.label != null) { - label = pastNode.label; - changed = true; - } - - for(BlockTransactionHashIndex txo : getTransactionOutputs()) { - Optional optPastTxo = pastNode.getTransactionOutputs().stream().filter(pastTxo -> pastTxo.equals(txo)).findFirst(); - if(optPastTxo.isPresent()) { - BlockTransactionHashIndex pastTxo = optPastTxo.get(); - if(txo.getLabel() == null && pastTxo.getLabel() != null) { - txo.setLabel(pastTxo.getLabel()); - changed = true; - } - if(txo.isSpent() && pastTxo.isSpent() && txo.getSpentBy().getLabel() == null && pastTxo.getSpentBy().getLabel() != null) { - txo.getSpentBy().setLabel(pastTxo.getSpentBy().getLabel()); - changed = true; - } - } - } - - for(WalletNode childNode : getChildren()) { - Optional optPastChildNode = pastNode.getChildren().stream().filter(node -> node.equals(childNode)).findFirst(); - if(optPastChildNode.isPresent()) { - changed |= childNode.copyLabels(optPastChildNode.get()); - } - } - - return changed; - } - public static String nodeRangesToString(Set nodes) { return nodeRangesToString(nodes.stream().map(WalletNode::getDerivationPath).collect(Collectors.toList())); } From 7bb07ab39eafc0de54d3dc2e19a444d39f9a1fc3 Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Tue, 22 Feb 2022 12:02:40 +0200 Subject: [PATCH 104/155] add bip47 keystores --- .../sparrowwallet/drongo/KeyDerivation.java | 8 + .../com/sparrowwallet/drongo/KeyPurpose.java | 5 + .../drongo/OutputDescriptor.java | 18 +- .../bip47/InvalidPaymentCodeException.java | 19 + .../drongo/bip47/NotSecp256k1Exception.java | 19 + .../drongo/bip47/PaymentAddress.java | 104 +++++ .../drongo/bip47/PaymentCode.java | 380 ++++++++++++++++++ .../drongo/bip47/SecretPoint.java | 53 +++ .../drongo/crypto/HDKeyDerivation.java | 4 + .../drongo/protocol/TransactionOutPoint.java | 13 + .../com/sparrowwallet/drongo/psbt/PSBT.java | 4 +- .../sparrowwallet/drongo/wallet/Keystore.java | 112 +++++- .../drongo/wallet/KeystoreSource.java | 8 +- .../drongo/wallet/PresetUtxoSelector.java | 16 + .../drongo/wallet/UtxoSelector.java | 3 + .../sparrowwallet/drongo/wallet/Wallet.java | 236 ++++++++--- src/main/java/module-info.java | 1 + .../drongo/OutputDescriptorTest.java | 6 +- .../drongo/bip47/PaymentCodeTest.java | 171 ++++++++ .../sparrowwallet/drongo/psbt/PSBTTest.java | 6 - .../drongo/wallet/WalletTest.java | 26 +- 21 files changed, 1116 insertions(+), 96 deletions(-) create mode 100644 src/main/java/com/sparrowwallet/drongo/bip47/InvalidPaymentCodeException.java create mode 100644 src/main/java/com/sparrowwallet/drongo/bip47/NotSecp256k1Exception.java create mode 100644 src/main/java/com/sparrowwallet/drongo/bip47/PaymentAddress.java create mode 100644 src/main/java/com/sparrowwallet/drongo/bip47/PaymentCode.java create mode 100644 src/main/java/com/sparrowwallet/drongo/bip47/SecretPoint.java create mode 100644 src/test/java/com/sparrowwallet/drongo/bip47/PaymentCodeTest.java diff --git a/src/main/java/com/sparrowwallet/drongo/KeyDerivation.java b/src/main/java/com/sparrowwallet/drongo/KeyDerivation.java index 2f811ec..2db24be 100644 --- a/src/main/java/com/sparrowwallet/drongo/KeyDerivation.java +++ b/src/main/java/com/sparrowwallet/drongo/KeyDerivation.java @@ -11,6 +11,10 @@ public class KeyDerivation { private final String derivationPath; private transient List derivation; + public KeyDerivation(String masterFingerprint, List derivation) { + this(masterFingerprint, writePath(derivation)); + } + public KeyDerivation(String masterFingerprint, String derivationPath) { this.masterFingerprint = masterFingerprint == null ? null : masterFingerprint.toLowerCase(); this.derivationPath = derivationPath; @@ -91,6 +95,10 @@ public class KeyDerivation { return true; } + public static List getBip47Derivation(int account) { + return List.of(new ChildNumber(47, true), new ChildNumber(Network.get() == Network.MAINNET ? 0 : 1, true), new ChildNumber(account, true)); + } + public KeyDerivation copy() { return new KeyDerivation(masterFingerprint, derivationPath); } diff --git a/src/main/java/com/sparrowwallet/drongo/KeyPurpose.java b/src/main/java/com/sparrowwallet/drongo/KeyPurpose.java index 0af33fb..5c14396 100644 --- a/src/main/java/com/sparrowwallet/drongo/KeyPurpose.java +++ b/src/main/java/com/sparrowwallet/drongo/KeyPurpose.java @@ -9,6 +9,11 @@ public enum KeyPurpose { public static final List DEFAULT_PURPOSES = List.of(RECEIVE, CHANGE); + //The receive derivation is also used for BIP47 notifications + public static final KeyPurpose NOTIFICATION = RECEIVE; + //The change derivation is reused for the send chain in BIP47 wallets + public static final KeyPurpose SEND = CHANGE; + private final ChildNumber pathIndex; KeyPurpose(ChildNumber pathIndex) { diff --git a/src/main/java/com/sparrowwallet/drongo/OutputDescriptor.java b/src/main/java/com/sparrowwallet/drongo/OutputDescriptor.java index 2e3f416..71823cb 100644 --- a/src/main/java/com/sparrowwallet/drongo/OutputDescriptor.java +++ b/src/main/java/com/sparrowwallet/drongo/OutputDescriptor.java @@ -500,18 +500,24 @@ public class OutputDescriptor { Utils.LexicographicByteArrayComparator lexicographicByteArrayComparator = new Utils.LexicographicByteArrayComparator(); sortedKeys.sort((o1, o2) -> { - List derivation1 = getDerivations(mapChildrenDerivations.get(o1)).get(0); - derivation1.add(0, o1.getKeyChildNumber()); - ECKey key1 = o1.getKey(derivation1); - List derivation2 = getDerivations(mapChildrenDerivations.get(o2)).get(0); - derivation2.add(0, o2.getKeyChildNumber()); - ECKey key2 = o2.getKey(derivation2); + ECKey key1 = getChildKeyForExtendedPubKey(o1); + ECKey key2 = getChildKeyForExtendedPubKey(o2); return lexicographicByteArrayComparator.compare(key1.getPubKey(), key2.getPubKey()); }); return sortedKeys; } + private ECKey getChildKeyForExtendedPubKey(ExtendedKey extendedKey) { + if(mapChildrenDerivations.get(extendedKey) == null) { + return extendedKey.getKey(); + } + + List derivation = getDerivations(mapChildrenDerivations.get(extendedKey)).get(0); + derivation.add(0, extendedKey.getKeyChildNumber()); + return extendedKey.getKey(derivation); + } + private List> getDerivations(String childDerivation) { Matcher matcher = MULTIPATH_PATTERN.matcher(childDerivation); if(matcher.find()) { diff --git a/src/main/java/com/sparrowwallet/drongo/bip47/InvalidPaymentCodeException.java b/src/main/java/com/sparrowwallet/drongo/bip47/InvalidPaymentCodeException.java new file mode 100644 index 0000000..336f465 --- /dev/null +++ b/src/main/java/com/sparrowwallet/drongo/bip47/InvalidPaymentCodeException.java @@ -0,0 +1,19 @@ +package com.sparrowwallet.drongo.bip47; + +public class InvalidPaymentCodeException extends Exception { + public InvalidPaymentCodeException() { + super(); + } + + public InvalidPaymentCodeException(String msg) { + super(msg); + } + + public InvalidPaymentCodeException(Throwable cause) { + super(cause); + } + + public InvalidPaymentCodeException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/src/main/java/com/sparrowwallet/drongo/bip47/NotSecp256k1Exception.java b/src/main/java/com/sparrowwallet/drongo/bip47/NotSecp256k1Exception.java new file mode 100644 index 0000000..51d4860 --- /dev/null +++ b/src/main/java/com/sparrowwallet/drongo/bip47/NotSecp256k1Exception.java @@ -0,0 +1,19 @@ +package com.sparrowwallet.drongo.bip47; + +public class NotSecp256k1Exception extends Exception { + public NotSecp256k1Exception() { + super(); + } + + public NotSecp256k1Exception(String msg) { + super(msg); + } + + public NotSecp256k1Exception(Throwable cause) { + super(cause); + } + + public NotSecp256k1Exception(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/src/main/java/com/sparrowwallet/drongo/bip47/PaymentAddress.java b/src/main/java/com/sparrowwallet/drongo/bip47/PaymentAddress.java new file mode 100644 index 0000000..fc9054d --- /dev/null +++ b/src/main/java/com/sparrowwallet/drongo/bip47/PaymentAddress.java @@ -0,0 +1,104 @@ +package com.sparrowwallet.drongo.bip47; + +import com.sparrowwallet.drongo.crypto.ECKey; +import org.bouncycastle.asn1.x9.X9ECParameters; +import org.bouncycastle.crypto.ec.CustomNamedCurves; +import org.bouncycastle.crypto.params.ECDomainParameters; +import org.bouncycastle.math.ec.ECPoint; + +import java.math.BigInteger; +import java.security.InvalidKeyException; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import java.security.spec.InvalidKeySpecException; + +public class PaymentAddress { + private static final X9ECParameters CURVE_PARAMS = CustomNamedCurves.getByName("secp256k1"); + private static final ECDomainParameters CURVE = new ECDomainParameters(CURVE_PARAMS.getCurve(), CURVE_PARAMS.getG(), CURVE_PARAMS.getN(), CURVE_PARAMS.getH()); + + private final PaymentCode paymentCode; + private final int index; + private final byte[] privKey; + + public PaymentAddress(PaymentCode paymentCode, int index, byte[] privKey) { + this.paymentCode = paymentCode; + this.index = index; + this.privKey = privKey; + } + + public ECKey getSendECKey() throws InvalidKeyException, NoSuchAlgorithmException, NoSuchProviderException, IllegalStateException, InvalidKeySpecException, NotSecp256k1Exception { + return getSendECKey(getSecretPoint()); + } + + public ECKey getReceiveECKey() throws InvalidKeyException, NoSuchAlgorithmException, NoSuchProviderException, IllegalStateException, InvalidKeySpecException, NotSecp256k1Exception { + return getReceiveECKey(getSecretPoint()); + } + + public SecretPoint getSharedSecret() throws InvalidKeyException, NoSuchAlgorithmException, NoSuchProviderException, IllegalStateException, InvalidKeySpecException { + return sharedSecret(); + } + + public BigInteger getSecretPoint() throws InvalidKeyException, NoSuchAlgorithmException, NoSuchProviderException, IllegalStateException, InvalidKeySpecException, NotSecp256k1Exception { + return secretPoint(); + } + + public ECPoint getECPoint() { + ECKey ecKey = ECKey.fromPublicOnly(paymentCode.getKey(index).getPubKey()); + return ecKey.getPubKeyPoint(); + } + + public byte[] hashSharedSecret() throws InvalidKeyException, NoSuchAlgorithmException, NoSuchProviderException, IllegalStateException, InvalidKeySpecException { + MessageDigest digest = MessageDigest.getInstance("SHA-256"); + return digest.digest(getSharedSecret().ECDHSecretAsBytes()); + } + + private ECPoint get_sG(BigInteger s) { + return CURVE_PARAMS.getG().multiply(s); + } + + private ECKey getSendECKey(BigInteger s) throws IllegalStateException { + ECPoint ecPoint = getECPoint(); + ECPoint sG = get_sG(s); + return ECKey.fromPublicOnly(ecPoint.add(sG).getEncoded(true)); + } + + private ECKey getReceiveECKey(BigInteger s) { + BigInteger privKeyValue = ECKey.fromPrivate(privKey).getPrivKey(); + return ECKey.fromPrivate(addSecp256k1(privKeyValue, s)); + } + + private BigInteger addSecp256k1(BigInteger b1, BigInteger b2) { + BigInteger ret = b1.add(b2); + + if(ret.bitLength() > CURVE.getN().bitLength()) { + return ret.mod(CURVE.getN()); + } + + return ret; + } + + private SecretPoint sharedSecret() throws InvalidKeySpecException, InvalidKeyException, IllegalStateException, NoSuchAlgorithmException, NoSuchProviderException { + return new SecretPoint(privKey, paymentCode.getKey(index).getPubKey()); + } + + private boolean isSecp256k1(BigInteger b) { + return b.compareTo(BigInteger.ONE) > 0 && b.bitLength() <= CURVE.getN().bitLength(); + } + + private BigInteger secretPoint() throws InvalidKeyException, NoSuchAlgorithmException, NoSuchProviderException, InvalidKeySpecException, NotSecp256k1Exception { + // + // convert hash to value 's' + // + BigInteger s = new BigInteger(1, hashSharedSecret()); + // + // check that 's' is on the secp256k1 curve + // + if(!isSecp256k1(s)) { + throw new NotSecp256k1Exception("Secret point not on Secp256k1 curve"); + } + + return s; + } +} + diff --git a/src/main/java/com/sparrowwallet/drongo/bip47/PaymentCode.java b/src/main/java/com/sparrowwallet/drongo/bip47/PaymentCode.java new file mode 100644 index 0000000..ea881e0 --- /dev/null +++ b/src/main/java/com/sparrowwallet/drongo/bip47/PaymentCode.java @@ -0,0 +1,380 @@ +package com.sparrowwallet.drongo.bip47; + +import com.sparrowwallet.drongo.address.Address; +import com.sparrowwallet.drongo.crypto.ChildNumber; +import com.sparrowwallet.drongo.crypto.DeterministicKey; +import com.sparrowwallet.drongo.crypto.ECKey; +import com.sparrowwallet.drongo.crypto.HDKeyDerivation; +import com.sparrowwallet.drongo.protocol.*; +import com.sparrowwallet.drongo.wallet.Keystore; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.crypto.Mac; +import javax.crypto.spec.SecretKeySpec; +import java.nio.BufferUnderflowException; +import java.nio.ByteBuffer; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +public class PaymentCode { + private static final Logger log = LoggerFactory.getLogger(PaymentCode.class); + + private static final int PUBLIC_KEY_Y_OFFSET = 2; + private static final int PUBLIC_KEY_X_OFFSET = 3; + private static final int CHAIN_OFFSET = 35; + private static final int PUBLIC_KEY_X_LEN = 32; + private static final int PUBLIC_KEY_Y_LEN = 1; + private static final int CHAIN_LEN = 32; + private static final int PAYLOAD_LEN = 80; + + private static final int SAMOURAI_FEATURE_BYTE = 79; + private static final int SAMOURAI_SEGWIT_BIT = 0; + + private final String strPaymentCode; + private final byte[] pubkey; + private final byte[] chain; + + private PaymentCode(String strPaymentCode, byte[] pubkey, byte[] chain) { + this.strPaymentCode = strPaymentCode; + this.pubkey = pubkey; + this.chain = chain; + } + + public PaymentCode(String payment_code) throws InvalidPaymentCodeException { + strPaymentCode = payment_code; + Map.Entry pubKeyChain = parse().entrySet().iterator().next(); + this.pubkey = pubKeyChain.getKey(); + this.chain = pubKeyChain.getValue(); + } + + public PaymentCode(byte[] payload) { + if(payload.length != 80) { + throw new IllegalArgumentException("Payment code must be 80 bytes"); + } + + pubkey = new byte[PUBLIC_KEY_Y_LEN + PUBLIC_KEY_X_LEN]; + chain = new byte[CHAIN_LEN]; + + System.arraycopy(payload, PUBLIC_KEY_Y_OFFSET, pubkey, 0, PUBLIC_KEY_Y_LEN + PUBLIC_KEY_X_LEN); + System.arraycopy(payload, CHAIN_OFFSET, chain, 0, CHAIN_LEN); + + strPaymentCode = makeV1(); + } + + public PaymentCode(byte[] pubkey, byte[] chain) { + this.pubkey = pubkey; + this.chain = chain; + strPaymentCode = makeV1(); + } + + public ECKey getNotificationKey() { + DeterministicKey masterPubKey = createMasterPubKeyFromBytes(); + return HDKeyDerivation.deriveChildKey(masterPubKey, ChildNumber.ZERO); + } + + public Address getNotificationAddress() { + return ScriptType.P2PKH.getAddress(getNotificationKey()); + } + + public ECKey getKey(int index) { + DeterministicKey masterPubKey = createMasterPubKeyFromBytes(); + return HDKeyDerivation.deriveChildKey(masterPubKey, new ChildNumber(index)); + } + + public byte[] getPayload() { + byte[] pcBytes = Base58.decodeChecked(strPaymentCode); + byte[] payload = new byte[PAYLOAD_LEN]; + System.arraycopy(pcBytes, 1, payload, 0, payload.length); + + return payload; + } + + public int getType() throws InvalidPaymentCodeException { + byte[] payload = getPayload(); + ByteBuffer bb = ByteBuffer.wrap(payload); + return bb.get(); + } + + public boolean isSegwitEnabled() { + return isBitSet(getPayload()[SAMOURAI_FEATURE_BYTE], SAMOURAI_SEGWIT_BIT); + } + + public String toString() { + return strPaymentCode; + } + + public static PaymentCode getPaymentCode(Transaction transaction, Keystore keystore) throws InvalidPaymentCodeException { + try { + TransactionInput txInput = getDesignatedInput(transaction); + ECKey pubKey = getDesignatedPubKey(txInput); + + ECKey notificationPrivKey = keystore.getBip47ExtendedPrivateKey().getKey(List.of(ChildNumber.ZERO_HARDENED, new ChildNumber(0))); + SecretPoint secretPoint = new SecretPoint(notificationPrivKey.getPrivKeyBytes(), pubKey.getPubKey()); + byte[] blindingMask = getMask(secretPoint.ECDHSecretAsBytes(), txInput.getOutpoint().bitcoinSerialize()); + byte[] blindedPaymentCode = getOpReturnData(transaction); + return new PaymentCode(PaymentCode.blind(blindedPaymentCode, blindingMask)); + } catch(Exception e) { + throw new InvalidPaymentCodeException("Could not determine payment code from transaction", e); + } + } + + public static TransactionInput getDesignatedInput(Transaction transaction) { + for(TransactionInput txInput : transaction.getInputs()) { + if(getDesignatedPubKey(txInput) != null) { + return txInput; + } + } + + throw new IllegalArgumentException("Cannot find designated input in notification transaction"); + } + + private static ECKey getDesignatedPubKey(TransactionInput txInput) { + for(ScriptChunk scriptChunk : txInput.getScriptSig().getChunks()) { + if(scriptChunk.isPubKey()) { + return scriptChunk.getPubKey(); + } + } + + for(ScriptChunk scriptChunk : txInput.getWitness().asScriptChunks()) { + if(scriptChunk.isPubKey()) { + return scriptChunk.getPubKey(); + } + } + + return null; + } + + public static byte[] getOpReturnData(Transaction transaction) { + for(TransactionOutput txOutput : transaction.getOutputs()) { + List scriptChunks = getOpReturnChunks(txOutput); + if(scriptChunks == null) { + continue; + } + + return scriptChunks.get(1).getData(); + } + + throw new IllegalArgumentException("Cannot find OP_RETURN output in notification transaction"); + } + + private static List getOpReturnChunks(TransactionOutput txOutput) { + List scriptChunks = txOutput.getScript().getChunks(); + if(scriptChunks.size() != 2) { + return null; + } + if(scriptChunks.get(0).getOpcode() != ScriptOpCodes.OP_RETURN) { + return null; + } + if(scriptChunks.get(1).getData() != null && scriptChunks.get(1).getData().length != 80) { + return null; + } + return scriptChunks; + } + + public static byte[] getMask(byte[] sPoint, byte[] oPoint) { + Mac sha512_HMAC; + byte[] mac_data = null; + + try { + sha512_HMAC = Mac.getInstance("HmacSHA512"); + SecretKeySpec secretkey = new SecretKeySpec(oPoint, "HmacSHA512"); + sha512_HMAC.init(secretkey); + mac_data = sha512_HMAC.doFinal(sPoint); + } catch(InvalidKeyException | NoSuchAlgorithmException ignored) { + //ignore + } + + return mac_data; + } + + public static byte[] blind(byte[] payload, byte[] mask) throws InvalidPaymentCodeException { + byte[] ret = new byte[PAYLOAD_LEN]; + byte[] pubkey = new byte[PUBLIC_KEY_X_LEN]; + byte[] chain = new byte[CHAIN_LEN]; + byte[] buf0 = new byte[PUBLIC_KEY_X_LEN]; + byte[] buf1 = new byte[CHAIN_LEN]; + + System.arraycopy(payload, 0, ret, 0, PAYLOAD_LEN); + + System.arraycopy(payload, PUBLIC_KEY_X_OFFSET, pubkey, 0, PUBLIC_KEY_X_LEN); + System.arraycopy(payload, CHAIN_OFFSET, chain, 0, CHAIN_LEN); + System.arraycopy(mask, 0, buf0, 0, PUBLIC_KEY_X_LEN); + System.arraycopy(mask, PUBLIC_KEY_X_LEN, buf1, 0, CHAIN_LEN); + + System.arraycopy(xor(pubkey, buf0), 0, ret, PUBLIC_KEY_X_OFFSET, PUBLIC_KEY_X_LEN); + System.arraycopy(xor(chain, buf1), 0, ret, CHAIN_OFFSET, CHAIN_LEN); + + return ret; + } + + private Map parse() throws InvalidPaymentCodeException { + byte[] pcBytes = Base58.decodeChecked(strPaymentCode); + + ByteBuffer bb = ByteBuffer.wrap(pcBytes); + if(bb.get() != 0x47) { + throw new InvalidPaymentCodeException("Invalid payment code version"); + } + + byte[] chain = new byte[CHAIN_LEN]; + byte[] pub = new byte[PUBLIC_KEY_X_LEN + PUBLIC_KEY_Y_LEN]; + + // type: + bb.get(); + // features: + bb.get(); + + bb.get(pub); + if(pub[0] != 0x02 && pub[0] != 0x03) { + throw new InvalidPaymentCodeException("Invalid public key"); + } + + bb.get(chain); + + return Map.of(pub, chain); + } + + private String makeV1() { + return make(0x01); + } + + private String make(int type) { + byte[] payload = new byte[PAYLOAD_LEN]; + byte[] payment_code = new byte[PAYLOAD_LEN + 1]; + + for(int i = 0; i < payload.length; i++) { + payload[i] = (byte) 0x00; + } + + // byte 0: type. + payload[0] = (byte) type; + // byte 1: features bit field. All bits must be zero except where specified elsewhere in this specification + // bit 0: Bitmessage notification + // bits 1-7: reserved + payload[1] = (byte) 0x00; + + // replace sign & x code (33 bytes) + System.arraycopy(pubkey, 0, payload, PUBLIC_KEY_Y_OFFSET, pubkey.length); + // replace chain code (32 bytes) + System.arraycopy(chain, 0, payload, CHAIN_OFFSET, chain.length); + + // add version byte + payment_code[0] = (byte) 0x47; + System.arraycopy(payload, 0, payment_code, 1, payload.length); + + // append checksum + return base58EncodeChecked(payment_code); + } + + public String makeSamouraiPaymentCode() throws InvalidPaymentCodeException { + byte[] payload = getPayload(); + // set bit0 = 1 in 'Samourai byte' for segwit. Can send/receive P2PKH, P2SH-P2WPKH, P2WPKH (bech32) + payload[SAMOURAI_FEATURE_BYTE] = setBit(payload[SAMOURAI_FEATURE_BYTE], SAMOURAI_SEGWIT_BIT); + byte[] payment_code = new byte[PAYLOAD_LEN + 1]; + // add version byte + payment_code[0] = (byte) 0x47; + System.arraycopy(payload, 0, payment_code, 1, payload.length); + + // append checksum + return base58EncodeChecked(payment_code); + } + + private String base58EncodeChecked(byte[] buf) { + byte[] checksum = Arrays.copyOfRange(Sha256Hash.hashTwice(buf), 0, 4); + byte[] bufChecked = new byte[buf.length + checksum.length]; + System.arraycopy(buf, 0, bufChecked, 0, buf.length); + System.arraycopy(checksum, 0, bufChecked, bufChecked.length - 4, checksum.length); + + return Base58.encode(bufChecked); + } + + private boolean isBitSet(byte b, int pos) { + byte test = 0; + return (setBit(test, pos) & b) > 0; + } + + private byte setBit(byte b, int pos) { + return (byte) (b | (1 << pos)); + } + + private DeterministicKey createMasterPubKeyFromBytes() { + return HDKeyDerivation.createMasterPubKeyFromBytes(pubkey, chain); + } + + private static byte[] xor(byte[] a, byte[] b) { + if(a.length != b.length) { + log.error("Invalid length for xor: " + a.length + " vs " + b.length); + return null; + } + + byte[] ret = new byte[a.length]; + + for(int i = 0; i < a.length; i++) { + ret[i] = (byte) ((int) b[i] ^ (int) a[i]); + } + + return ret; + } + + public boolean isValid() { + try { + byte[] pcodeBytes = Base58.decodeChecked(strPaymentCode); + + ByteBuffer byteBuffer = ByteBuffer.wrap(pcodeBytes); + if(byteBuffer.get() != 0x47) { + throw new InvalidPaymentCodeException("Invalid version: " + strPaymentCode); + } else { + byte[] chain = new byte[32]; + byte[] pub = new byte[33]; + // type: + byteBuffer.get(); + // feature: + byteBuffer.get(); + byteBuffer.get(pub); + byteBuffer.get(chain); + + ByteBuffer pubBytes = ByteBuffer.wrap(pub); + int firstByte = pubBytes.get(); + return firstByte == 0x02 || firstByte == 0x03; + } + } catch(BufferUnderflowException | InvalidPaymentCodeException bue) { + return false; + } + } + + public static PaymentCode fromString(String strPaymentCode) { + try { + return new PaymentCode(strPaymentCode); + } catch(InvalidPaymentCodeException e) { + log.error("Invalid payment code", e); + } + + return null; + } + + public PaymentCode copy() { + return new PaymentCode(strPaymentCode, pubkey, chain); + } + + @Override + public boolean equals(Object o) { + if(this == o) { + return true; + } + if(o == null || getClass() != o.getClass()) { + return false; + } + + PaymentCode that = (PaymentCode) o; + return strPaymentCode.equals(that.strPaymentCode); + } + + @Override + public int hashCode() { + return strPaymentCode.hashCode(); + } +} + diff --git a/src/main/java/com/sparrowwallet/drongo/bip47/SecretPoint.java b/src/main/java/com/sparrowwallet/drongo/bip47/SecretPoint.java new file mode 100644 index 0000000..60e3054 --- /dev/null +++ b/src/main/java/com/sparrowwallet/drongo/bip47/SecretPoint.java @@ -0,0 +1,53 @@ +package com.sparrowwallet.drongo.bip47; + +import org.bouncycastle.jce.ECNamedCurveTable; +import org.bouncycastle.jce.spec.ECParameterSpec; +import org.bouncycastle.jce.spec.ECPrivateKeySpec; +import org.bouncycastle.jce.spec.ECPublicKeySpec; + +import javax.crypto.KeyAgreement; +import javax.crypto.SecretKey; +import java.math.BigInteger; +import java.security.*; +import java.security.spec.InvalidKeySpecException; + +public class SecretPoint { + private static final ECParameterSpec params = ECNamedCurveTable.getParameterSpec("secp256k1"); + private static final String KEY_PROVIDER = "BC"; + + private final PrivateKey privKey; + private final PublicKey pubKey; + private final KeyFactory kf; + + static { + Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider()); + } + + public SecretPoint(byte[] dataPrv, byte[] dataPub) throws InvalidKeySpecException, InvalidKeyException, IllegalStateException, NoSuchAlgorithmException, NoSuchProviderException { + kf = KeyFactory.getInstance("ECDH", KEY_PROVIDER); + privKey = loadPrivateKey(dataPrv); + pubKey = loadPublicKey(dataPub); + } + + public byte[] ECDHSecretAsBytes() throws InvalidKeyException, IllegalStateException, NoSuchAlgorithmException, NoSuchProviderException { + return ECDHSecret().getEncoded(); + } + + private SecretKey ECDHSecret() throws InvalidKeyException, IllegalStateException, NoSuchAlgorithmException, NoSuchProviderException { + KeyAgreement ka = KeyAgreement.getInstance("ECDH", KEY_PROVIDER); + ka.init(privKey); + ka.doPhase(pubKey, true); + return ka.generateSecret("AES"); + } + + private PublicKey loadPublicKey(byte[] data) throws InvalidKeySpecException { + ECPublicKeySpec pubKey = new ECPublicKeySpec(params.getCurve().decodePoint(data), params); + return kf.generatePublic(pubKey); + } + + private PrivateKey loadPrivateKey(byte[] data) throws InvalidKeySpecException { + ECPrivateKeySpec prvkey = new ECPrivateKeySpec(new BigInteger(1, data), params); + return kf.generatePrivate(prvkey); + } +} + diff --git a/src/main/java/com/sparrowwallet/drongo/crypto/HDKeyDerivation.java b/src/main/java/com/sparrowwallet/drongo/crypto/HDKeyDerivation.java index f926dee..5f93f04 100644 --- a/src/main/java/com/sparrowwallet/drongo/crypto/HDKeyDerivation.java +++ b/src/main/java/com/sparrowwallet/drongo/crypto/HDKeyDerivation.java @@ -38,6 +38,10 @@ public class HDKeyDerivation { return new DeterministicKey(childNumberPath, chainCode, priv, null); } + public static DeterministicKey createMasterPubKeyFromBytes(byte[] pubKeyBytes, byte[] chainCode) { + return new DeterministicKey(List.of(), chainCode, new LazyECPoint(ECKey.CURVE.getCurve(), pubKeyBytes), null, null); + } + public static DeterministicKey deriveChildKey(DeterministicKey parent, ChildNumber childNumber) throws HDDerivationException { if(parent.isPubKeyOnly()) { RawKeyBytes rawKey = deriveChildKeyBytesFromPublic(parent, childNumber); diff --git a/src/main/java/com/sparrowwallet/drongo/protocol/TransactionOutPoint.java b/src/main/java/com/sparrowwallet/drongo/protocol/TransactionOutPoint.java index 935673f..ffe3e02 100644 --- a/src/main/java/com/sparrowwallet/drongo/protocol/TransactionOutPoint.java +++ b/src/main/java/com/sparrowwallet/drongo/protocol/TransactionOutPoint.java @@ -3,6 +3,7 @@ package com.sparrowwallet.drongo.protocol; import com.sparrowwallet.drongo.Utils; import com.sparrowwallet.drongo.address.Address; +import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; import java.util.Objects; @@ -51,6 +52,18 @@ public class TransactionOutPoint extends ChildMessage { this.addresses = addresses; } + public byte[] bitcoinSerialize() { + try { + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + bitcoinSerializeToStream(outputStream); + return outputStream.toByteArray(); + } catch (IOException e) { + //can't happen + } + + return null; + } + @Override protected void bitcoinSerializeToStream(OutputStream stream) throws IOException { stream.write(hash.getReversedBytes()); diff --git a/src/main/java/com/sparrowwallet/drongo/psbt/PSBT.java b/src/main/java/com/sparrowwallet/drongo/psbt/PSBT.java index e77a165..51c6f39 100644 --- a/src/main/java/com/sparrowwallet/drongo/psbt/PSBT.java +++ b/src/main/java/com/sparrowwallet/drongo/psbt/PSBT.java @@ -136,8 +136,8 @@ public class PSBT { outputNodes.add(wallet.getWalletAddresses().getOrDefault(address, null)); } } catch(NonStandardScriptException e) { - //Should never happen - throw new IllegalArgumentException(e); + //Ignore, likely OP_RETURN output + outputNodes.add(null); } } diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/Keystore.java b/src/main/java/com/sparrowwallet/drongo/wallet/Keystore.java index db40a68..b4079e5 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/Keystore.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/Keystore.java @@ -4,11 +4,20 @@ import com.sparrowwallet.drongo.ExtendedKey; import com.sparrowwallet.drongo.KeyDerivation; import com.sparrowwallet.drongo.KeyPurpose; import com.sparrowwallet.drongo.Utils; +import com.sparrowwallet.drongo.bip47.PaymentAddress; +import com.sparrowwallet.drongo.bip47.PaymentCode; import com.sparrowwallet.drongo.crypto.*; +import com.sparrowwallet.drongo.policy.PolicyType; +import com.sparrowwallet.drongo.protocol.ScriptType; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import java.util.ArrayList; import java.util.List; public class Keystore extends Persistable { + private static final Logger log = LoggerFactory.getLogger(Keystore.class); + public static final String DEFAULT_LABEL = "Keystore 1"; public static final int MAX_LABEL_LENGTH = 16; @@ -17,9 +26,13 @@ public class Keystore extends Persistable { private WalletModel walletModel = WalletModel.SPARROW; private KeyDerivation keyDerivation; private ExtendedKey extendedPublicKey; + private PaymentCode externalPaymentCode; private MasterPrivateExtendedKey masterPrivateExtendedKey; private DeterministicSeed seed; + //For BIP47 keystores - not persisted but must be unencrypted to generate keys + private ExtendedKey bip47ExtendedPrivateKey; + public Keystore() { this(DEFAULT_LABEL); } @@ -72,6 +85,14 @@ public class Keystore extends Persistable { this.extendedPublicKey = extendedPublicKey; } + public PaymentCode getExternalPaymentCode() { + return externalPaymentCode; + } + + public void setExternalPaymentCode(PaymentCode paymentCode) { + this.externalPaymentCode = paymentCode; + } + public boolean hasMasterPrivateExtendedKey() { return masterPrivateExtendedKey != null; } @@ -96,10 +117,34 @@ public class Keystore extends Persistable { this.seed = seed; } - public boolean hasPrivateKey() { + public boolean hasMasterPrivateKey() { return hasSeed() || hasMasterPrivateExtendedKey(); } + public boolean hasPrivateKey() { + return hasMasterPrivateKey() || (source == KeystoreSource.SW_PAYMENT_CODE && bip47ExtendedPrivateKey != null); + } + + public PaymentCode getPaymentCode() { + DeterministicKey bip47Key = bip47ExtendedPrivateKey.getKey(); + return new PaymentCode(bip47Key.getPubKey(), bip47Key.getChainCode()); + } + + public ExtendedKey getBip47ExtendedPrivateKey() { + return bip47ExtendedPrivateKey; + } + + public void setBip47ExtendedPrivateKey(ExtendedKey bip47ExtendedPrivateKey) { + this.bip47ExtendedPrivateKey = bip47ExtendedPrivateKey; + } + + public PaymentAddress getPaymentAddress(KeyPurpose keyPurpose, int index) { + List derivation = keyDerivation.getDerivation(); + ChildNumber derivationStart = keyDerivation.getDerivation().isEmpty() ? ChildNumber.ZERO_HARDENED : keyDerivation.getDerivation().get(derivation.size() - 1); + DeterministicKey privateKey = bip47ExtendedPrivateKey.getKey(List.of(derivationStart, new ChildNumber(keyPurpose == KeyPurpose.SEND ? 0 : index))); + return new PaymentAddress(externalPaymentCode, keyPurpose == KeyPurpose.SEND ? index : 0, privateKey.getPrivKeyBytes()); + } + public DeterministicKey getMasterPrivateKey() throws MnemonicException { if(seed == null && masterPrivateExtendedKey == null) { throw new IllegalArgumentException("Keystore does not contain a master private key, or seed to derive one from"); @@ -136,22 +181,44 @@ public class Keystore extends Persistable { return ExtendedKey.fromDescriptor(xprv.toString()); } - public DeterministicKey getKey(WalletNode walletNode) throws MnemonicException { - return getKey(walletNode.getKeyPurpose(), walletNode.getIndex()); - } + public ECKey getKey(WalletNode walletNode) throws MnemonicException { + if(source == KeystoreSource.SW_PAYMENT_CODE) { + try { + if(walletNode.getKeyPurpose() != KeyPurpose.RECEIVE) { + throw new IllegalArgumentException("Cannot get private key for non-receive chain"); + } + + PaymentAddress paymentAddress = getPaymentAddress(walletNode.getKeyPurpose(), walletNode.getIndex()); + return paymentAddress.getReceiveECKey(); + } catch(IllegalArgumentException e) { + throw new IllegalArgumentException("Invalid payment code " + externalPaymentCode, e); + } catch(Exception e) { + log.error("Cannot get receive private key at index " + walletNode.getIndex() + " for payment code " + externalPaymentCode, e); + } + } - public DeterministicKey getKey(KeyPurpose keyPurpose, int keyIndex) throws MnemonicException { ExtendedKey extendedPrivateKey = getExtendedPrivateKey(); - List derivation = List.of(extendedPrivateKey.getKeyChildNumber(), keyPurpose.getPathIndex(), new ChildNumber(keyIndex)); + List derivation = new ArrayList<>(); + derivation.add(extendedPrivateKey.getKeyChildNumber()); + derivation.addAll(walletNode.getDerivation()); return extendedPrivateKey.getKey(derivation); } - public DeterministicKey getPubKey(WalletNode walletNode) { - return getPubKey(walletNode.getKeyPurpose(), walletNode.getIndex()); - } + public ECKey getPubKey(WalletNode walletNode) { + if(source == KeystoreSource.SW_PAYMENT_CODE) { + try { + PaymentAddress paymentAddress = getPaymentAddress(walletNode.getKeyPurpose(), walletNode.getIndex()); + return walletNode.getKeyPurpose() == KeyPurpose.RECEIVE ? ECKey.fromPublicOnly(paymentAddress.getReceiveECKey()) : paymentAddress.getSendECKey(); + } catch(IllegalArgumentException e) { + throw new IllegalArgumentException("Invalid payment code " + externalPaymentCode, e); + } catch(Exception e) { + log.error("Cannot get receive private key at index " + walletNode.getIndex() + " for payment code " + externalPaymentCode, e); + } + } - public DeterministicKey getPubKey(KeyPurpose keyPurpose, int keyIndex) { - List derivation = List.of(extendedPublicKey.getKeyChildNumber(), keyPurpose.getPathIndex(), new ChildNumber(keyIndex)); + List derivation = new ArrayList<>(); + derivation.add(extendedPublicKey.getKeyChildNumber()); + derivation.addAll(walletNode.getDerivation()); return extendedPublicKey.getKey(derivation); } @@ -225,6 +292,16 @@ public class Keystore extends Persistable { } } } + + if(source == KeystoreSource.SW_PAYMENT_CODE) { + if(externalPaymentCode == null) { + throw new InvalidKeystoreException("Source of " + source + " but no payment code is present"); + } + + if(bip47ExtendedPrivateKey == null) { + throw new InvalidKeystoreException("Source of " + source + " but no extended private key is present"); + } + } } public Keystore copy() { @@ -244,6 +321,12 @@ public class Keystore extends Persistable { if(seed != null) { copy.setSeed(seed.copy()); } + if(externalPaymentCode != null) { + copy.setExternalPaymentCode(externalPaymentCode.copy()); + } + if(bip47ExtendedPrivateKey != null) { + copy.setBip47ExtendedPrivateKey(bip47ExtendedPrivateKey.copy()); + } return copy; } @@ -274,6 +357,13 @@ public class Keystore extends Persistable { keystore.setWalletModel(WalletModel.SPARROW); keystore.setKeyDerivation(new KeyDerivation(masterFingerprint, KeyDerivation.writePath(derivation))); keystore.setExtendedPublicKey(ExtendedKey.fromDescriptor(xpub.toString())); + + int account = ScriptType.getScriptTypesForPolicyType(PolicyType.SINGLE).stream() + .mapToInt(scriptType -> scriptType.getAccount(keystore.getKeyDerivation().getDerivationPath())).filter(idx -> idx > -1).findFirst().orElse(0); + List bip47Derivation = KeyDerivation.getBip47Derivation(account); + DeterministicKey bip47Key = xprv.getKey(bip47Derivation); + ExtendedKey bip47ExtendedPrivateKey = new ExtendedKey(bip47Key, bip47Key.getParentFingerprint(), bip47Derivation.get(bip47Derivation.size() - 1)); + keystore.setBip47ExtendedPrivateKey(ExtendedKey.fromDescriptor(bip47ExtendedPrivateKey.toString())); } public boolean isEncrypted() { diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/KeystoreSource.java b/src/main/java/com/sparrowwallet/drongo/wallet/KeystoreSource.java index b3c4b31..a98bbe0 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/KeystoreSource.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/KeystoreSource.java @@ -1,9 +1,13 @@ package com.sparrowwallet.drongo.wallet; public enum KeystoreSource { - HW_USB("Connected Hardware Wallet"), HW_AIRGAPPED("Airgapped Hardware Wallet"), SW_SEED("Software Wallet"), SW_WATCH("Watch Only Wallet"); + HW_USB("Connected Hardware Wallet"), + HW_AIRGAPPED("Airgapped Hardware Wallet"), + SW_SEED("Software Wallet"), + SW_WATCH("Watch Only Wallet"), + SW_PAYMENT_CODE("Payment Code Wallet"); - private String displayName; + private final String displayName; KeystoreSource(String displayName) { this.displayName = displayName; diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/PresetUtxoSelector.java b/src/main/java/com/sparrowwallet/drongo/wallet/PresetUtxoSelector.java index 2ad8147..090014c 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/PresetUtxoSelector.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/PresetUtxoSelector.java @@ -7,9 +7,16 @@ import java.util.stream.Collectors; public class PresetUtxoSelector extends SingleSetUtxoSelector { private final Collection presetUtxos; + private final boolean maintainOrder; public PresetUtxoSelector(Collection presetUtxos) { this.presetUtxos = presetUtxos; + this.maintainOrder = false; + } + + public PresetUtxoSelector(Collection presetUtxos, boolean maintainOrder) { + this.presetUtxos = presetUtxos; + this.maintainOrder = maintainOrder; } @Override @@ -26,10 +33,19 @@ public class PresetUtxoSelector extends SingleSetUtxoSelector { } } + if(maintainOrder && utxos.containsAll(presetUtxos)) { + return presetUtxos; + } + return utxos; } public Collection getPresetUtxos() { return presetUtxos; } + + @Override + public boolean shuffleInputs() { + return !maintainOrder; + } } diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/UtxoSelector.java b/src/main/java/com/sparrowwallet/drongo/wallet/UtxoSelector.java index 0051ba0..4d6efa5 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/UtxoSelector.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/UtxoSelector.java @@ -5,4 +5,7 @@ import java.util.List; public interface UtxoSelector { List> selectSets(long targetValue, Collection candidates); + default boolean shuffleInputs() { + return true; + } } diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java index 5b19bff..6e2ea79 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java @@ -1,11 +1,10 @@ package com.sparrowwallet.drongo.wallet; -import com.sparrowwallet.drongo.BitcoinUnit; -import com.sparrowwallet.drongo.KeyDerivation; -import com.sparrowwallet.drongo.KeyPurpose; -import com.sparrowwallet.drongo.Network; +import com.sparrowwallet.drongo.*; import com.sparrowwallet.drongo.address.Address; +import com.sparrowwallet.drongo.bip47.PaymentCode; import com.sparrowwallet.drongo.crypto.ChildNumber; +import com.sparrowwallet.drongo.crypto.DeterministicKey; import com.sparrowwallet.drongo.crypto.ECKey; import com.sparrowwallet.drongo.crypto.Key; import com.sparrowwallet.drongo.policy.Policy; @@ -109,7 +108,7 @@ public class Wallet extends Persistable implements Comparable { throw new IllegalStateException("Cannot add child wallet to existing child wallet"); } - if(childWallet.containsPrivateKeys() && childWallet.isEncrypted()) { + if(childWallet.containsMasterPrivateKeys() && childWallet.isEncrypted()) { throw new IllegalStateException("Cannot derive child wallet xpub from encrypted wallet"); } @@ -136,7 +135,7 @@ public class Wallet extends Persistable implements Comparable { childDerivation.add(standardAccount.getChildNumber()); } - if(keystore.hasPrivateKey()) { + if(keystore.hasMasterPrivateKey()) { try { Keystore derivedKeystore = keystore.hasSeed() ? Keystore.fromSeed(keystore.getSeed(), childDerivation) : Keystore.fromMasterPrivateExtendedKey(keystore.getMasterPrivateExtendedKey(), childDerivation); keystore.setKeyDerivation(derivedKeystore.getKeyDerivation()); @@ -167,6 +166,65 @@ public class Wallet extends Persistable implements Comparable { return null; } + public Wallet addChildWallet(PaymentCode externalPaymentCode, ScriptType childScriptType, BlockTransactionHashIndex notificationOutput, BlockTransaction notificationTransaction) { + Wallet bip47Wallet = addChildWallet(externalPaymentCode, childScriptType); + WalletNode notificationNode = bip47Wallet.getNode(KeyPurpose.NOTIFICATION); + notificationNode.getTransactionOutputs().add(notificationOutput); + bip47Wallet.updateTransactions(Map.of(notificationTransaction.getHash(), notificationTransaction)); + + return bip47Wallet; + } + + public Wallet addChildWallet(PaymentCode externalPaymentCode, ScriptType childScriptType) { + if(policyType != PolicyType.SINGLE) { + throw new IllegalStateException("Cannot add payment code wallet to " + policyType.getName() + " wallet"); + } + + if(scriptType != P2PKH && scriptType != P2WPKH) { + throw new IllegalStateException("Cannot add payment code wallet to " + scriptType.getName() + " wallet"); + } + + Keystore masterKeystore = getKeystores().get(0); + if(masterKeystore.getBip47ExtendedPrivateKey() == null) { + throw new IllegalStateException("Cannot add payment code wallet, BIP47 extended private key not present"); + } + + Wallet childWallet = new Wallet(childScriptType + "-" + externalPaymentCode.toString()); + childWallet.setPolicyType(PolicyType.SINGLE); + childWallet.setScriptType(childScriptType); + childWallet.setGapLimit(5); + + Keystore keystore = new Keystore("BIP47"); + keystore.setSource(KeystoreSource.SW_PAYMENT_CODE); + keystore.setWalletModel(WalletModel.SPARROW); + List derivation = KeyDerivation.getBip47Derivation(getAccountIndex()); + keystore.setKeyDerivation(new KeyDerivation(masterKeystore.getKeyDerivation().getMasterFingerprint(), derivation)); + keystore.setExternalPaymentCode(externalPaymentCode); + keystore.setBip47ExtendedPrivateKey(masterKeystore.getBip47ExtendedPrivateKey()); + DeterministicKey pubKey = keystore.getBip47ExtendedPrivateKey().getKey().dropPrivateBytes().dropParent(); + keystore.setExtendedPublicKey(new ExtendedKey(pubKey, keystore.getBip47ExtendedPrivateKey().getParentFingerprint(), derivation.get(derivation.size() - 1))); + + childWallet.getKeystores().add(keystore); + childWallet.setDefaultPolicy(Policy.getPolicy(PolicyType.SINGLE, scriptType, childWallet.getKeystores(), 1)); + + childWallet.setMasterWallet(this); + getChildWallets().add(childWallet); + return childWallet; + } + + public Wallet getChildWallet(PaymentCode externalPaymentCode, ScriptType childScriptType) { + for(Wallet childWallet : getChildWallets()) { + if(childWallet.getKeystores().size() == 1 && externalPaymentCode != null && childWallet.getScriptType() == childScriptType && + childWallet.getKeystores().get(0).getExternalPaymentCode() != null && + (externalPaymentCode.equals(childWallet.getKeystores().get(0).getExternalPaymentCode()) || + externalPaymentCode.getNotificationAddress().equals(childWallet.getKeystores().get(0).getExternalPaymentCode().getNotificationAddress()))) { + return childWallet; + } + } + + return null; + } + public List getAllWallets() { List allWallets = new ArrayList<>(); Wallet masterWallet = isMasterWallet() ? this : getMasterWallet(); @@ -175,6 +233,70 @@ public class Wallet extends Persistable implements Comparable { return allWallets; } + public boolean hasPaymentCode() { + return getKeystores().size() == 1 && getKeystores().get(0).getBip47ExtendedPrivateKey() != null; + } + + public PaymentCode getPaymentCode() { + if(hasPaymentCode()) { + return getKeystores().get(0).getPaymentCode(); + } + + return null; + } + + public Wallet getNotificationWallet() { + if(isMasterWallet() && hasPaymentCode()) { + Wallet notificationWallet = new Wallet(); + notificationWallet.setPolicyType(PolicyType.SINGLE); + notificationWallet.setScriptType(ScriptType.P2PKH); + notificationWallet.setGapLimit(0); + + Keystore masterKeystore = getKeystores().get(0); + + Keystore keystore = new Keystore(); + keystore.setSource(KeystoreSource.SW_WATCH); + keystore.setWalletModel(WalletModel.SPARROW); + keystore.setKeyDerivation(new KeyDerivation(masterKeystore.getKeyDerivation().getMasterFingerprint(), KeyDerivation.getBip47Derivation(getAccountIndex()))); + keystore.setExtendedPublicKey(masterKeystore.getBip47ExtendedPrivateKey()); + keystore.setBip47ExtendedPrivateKey(masterKeystore.getBip47ExtendedPrivateKey()); + + notificationWallet.getKeystores().add(keystore); + notificationWallet.setDefaultPolicy(Policy.getPolicy(PolicyType.SINGLE, ScriptType.P2PKH, notificationWallet.getKeystores(), 1)); + + return notificationWallet; + } + + return null; + } + + public Map getNotificationTransaction(PaymentCode externalPaymentCode) { + Address notificationAddress = externalPaymentCode.getNotificationAddress(); + for(Map.Entry txoEntry : getWalletTxos().entrySet()) { + if(txoEntry.getKey().isSpent()) { + BlockTransaction blockTransaction = transactions.get(txoEntry.getKey().getSpentBy().getHash()); + if(blockTransaction != null) { + for(TransactionOutput txOutput : blockTransaction.getTransaction().getOutputs()) { + if(notificationAddress.equals(txOutput.getScript().getToAddress())) { + try { + PaymentCode.getOpReturnData(blockTransaction.getTransaction()); + return Map.of(blockTransaction, txoEntry.getValue()); + } catch(Exception e) { + //ignore + } + } + } + } + } + } + + return Collections.emptyMap(); + } + + public boolean isBip47() { + return !isMasterWallet() && getKeystores().size() == 1 && getKeystores().get(0).getSource() == KeystoreSource.SW_PAYMENT_CODE; + } + public StandardAccount getStandardAccountType() { int accountIndex = getAccountIndex(); return Arrays.stream(StandardAccount.values()).filter(standardAccount -> standardAccount.getChildNumber().num() == accountIndex).findFirst().orElse(null); @@ -454,10 +576,6 @@ public class Wallet extends Persistable implements Comparable { } public ECKey getPubKey(WalletNode node) { - return getPubKey(node.getKeyPurpose(), node.getIndex()); - } - - public ECKey getPubKey(KeyPurpose keyPurpose, int index) { if(policyType == PolicyType.MULTI) { throw new IllegalStateException("Attempting to retrieve a single key for a multisig policy wallet"); } else if(policyType == PolicyType.CUSTOM) { @@ -465,33 +583,25 @@ public class Wallet extends Persistable implements Comparable { } Keystore keystore = getKeystores().get(0); - return keystore.getPubKey(keyPurpose, index); + return keystore.getPubKey(node); } public List getPubKeys(WalletNode node) { - return getPubKeys(node.getKeyPurpose(), node.getIndex()); - } - - public List getPubKeys(KeyPurpose keyPurpose, int index) { if(policyType == PolicyType.SINGLE) { throw new IllegalStateException("Attempting to retrieve multiple keys for a singlesig policy wallet"); } else if(policyType == PolicyType.CUSTOM) { throw new UnsupportedOperationException("Cannot determine public keys for a custom policy"); } - return getKeystores().stream().map(keystore -> keystore.getPubKey(keyPurpose, index)).collect(Collectors.toList()); + return getKeystores().stream().map(keystore -> keystore.getPubKey(node)).collect(Collectors.toList()); } public Address getAddress(WalletNode node) { - return getAddress(node.getKeyPurpose(), node.getIndex()); - } - - public Address getAddress(KeyPurpose keyPurpose, int index) { if(policyType == PolicyType.SINGLE) { - ECKey pubKey = getPubKey(keyPurpose, index); + ECKey pubKey = getPubKey(node); return scriptType.getAddress(pubKey); } else if(policyType == PolicyType.MULTI) { - List pubKeys = getPubKeys(keyPurpose, index); + List pubKeys = getPubKeys(node); Script script = ScriptType.MULTISIG.getOutputScript(defaultPolicy.getNumSignaturesRequired(), pubKeys); return scriptType.getAddress(script); } else { @@ -500,15 +610,11 @@ public class Wallet extends Persistable implements Comparable { } public Script getOutputScript(WalletNode node) { - return getOutputScript(node.getKeyPurpose(), node.getIndex()); - } - - public Script getOutputScript(KeyPurpose keyPurpose, int index) { if(policyType == PolicyType.SINGLE) { - ECKey pubKey = getPubKey(keyPurpose, index); + ECKey pubKey = getPubKey(node); return scriptType.getOutputScript(pubKey); } else if(policyType == PolicyType.MULTI) { - List pubKeys = getPubKeys(keyPurpose, index); + List pubKeys = getPubKeys(node); Script script = ScriptType.MULTISIG.getOutputScript(defaultPolicy.getNumSignaturesRequired(), pubKeys); return scriptType.getOutputScript(script); } else { @@ -517,15 +623,11 @@ public class Wallet extends Persistable implements Comparable { } public String getOutputDescriptor(WalletNode node) { - return getOutputDescriptor(node.getKeyPurpose(), node.getIndex()); - } - - public String getOutputDescriptor(KeyPurpose keyPurpose, int index) { if(policyType == PolicyType.SINGLE) { - ECKey pubKey = getPubKey(keyPurpose, index); + ECKey pubKey = getPubKey(node); return scriptType.getOutputDescriptor(pubKey); } else if(policyType == PolicyType.MULTI) { - List pubKeys = getPubKeys(keyPurpose, index); + List pubKeys = getPubKeys(node); Script script = ScriptType.MULTISIG.getOutputScript(defaultPolicy.getNumSignaturesRequired(), pubKeys); return scriptType.getOutputDescriptor(script); } else { @@ -533,10 +635,20 @@ public class Wallet extends Persistable implements Comparable { } } + public List getWalletKeyPurposes() { + return isBip47() ? List.of(KeyPurpose.RECEIVE) : KeyPurpose.DEFAULT_PURPOSES; + } + + public KeyPurpose getChangeKeyPurpose() { + return isBip47() ? KeyPurpose.RECEIVE : KeyPurpose.CHANGE; + } + public Map> getWalletNodes() { Map> walletNodes = new LinkedHashMap<>(); - getNode(KeyPurpose.RECEIVE).getChildren().forEach(childNode -> walletNodes.put(childNode, childNode.getTransactionOutputs())); - getNode(KeyPurpose.CHANGE).getChildren().forEach(childNode -> walletNodes.put(childNode, childNode.getTransactionOutputs())); + for(KeyPurpose keyPurpose : KeyPurpose.DEFAULT_PURPOSES) { + getNode(keyPurpose).getChildren().forEach(childNode -> walletNodes.put(childNode, childNode.getTransactionOutputs())); + } + return walletNodes; } @@ -546,8 +658,10 @@ public class Wallet extends Persistable implements Comparable { public Map getWalletAddresses() { Map walletAddresses = new LinkedHashMap<>(); - getWalletAddresses(walletAddresses, getNode(KeyPurpose.RECEIVE)); - getWalletAddresses(walletAddresses, getNode(KeyPurpose.CHANGE)); + for(KeyPurpose keyPurpose : getWalletKeyPurposes()) { + getWalletAddresses(walletAddresses, getNode(keyPurpose)); + } + return walletAddresses; } @@ -562,10 +676,18 @@ public class Wallet extends Persistable implements Comparable { } public Map getWalletOutputScripts() { - return getWalletOutputScripts(KeyPurpose.RECEIVE, KeyPurpose.CHANGE); + return getWalletOutputScripts(getWalletKeyPurposes()); } - public Map getWalletOutputScripts(KeyPurpose... keyPurposes) { + public Map getWalletOutputScripts(KeyPurpose keyPurpose) { + if(!getWalletKeyPurposes().contains(keyPurpose)) { + return Collections.emptyMap(); + } + + return getWalletOutputScripts(List.of(keyPurpose)); + } + + private Map getWalletOutputScripts(List keyPurposes) { Map walletOutputScripts = new LinkedHashMap<>(); for(KeyPurpose keyPurpose : keyPurposes) { getWalletOutputScripts(walletOutputScripts, getNode(keyPurpose)); @@ -593,8 +715,10 @@ public class Wallet extends Persistable implements Comparable { public Map getWalletTxos() { Map walletTxos = new TreeMap<>(); - getWalletTxos(walletTxos, getNode(KeyPurpose.RECEIVE)); - getWalletTxos(walletTxos, getNode(KeyPurpose.CHANGE)); + for(KeyPurpose keyPurpose : getWalletKeyPurposes()) { + getWalletTxos(walletTxos, getNode(keyPurpose)); + } + return walletTxos; } @@ -612,8 +736,10 @@ public class Wallet extends Persistable implements Comparable { public Map getWalletUtxos(boolean includeSpentMempoolOutputs) { Map walletUtxos = new TreeMap<>(); - getWalletUtxos(walletUtxos, getNode(KeyPurpose.RECEIVE), includeSpentMempoolOutputs); - getWalletUtxos(walletUtxos, getNode(KeyPurpose.CHANGE), includeSpentMempoolOutputs); + for(KeyPurpose keyPurpose : getWalletKeyPurposes()) { + getWalletUtxos(walletUtxos, getNode(keyPurpose), includeSpentMempoolOutputs); + } + return walletUtxos; } @@ -785,7 +911,7 @@ public class Wallet extends Persistable implements Comparable { } for(int i = 1; i < numSets; i+=2) { - WalletNode mixNode = getFreshNode(KeyPurpose.CHANGE); + WalletNode mixNode = getFreshNode(getChangeKeyPurpose()); txExcludedChangeNodes.add(mixNode); Payment fakeMixPayment = new Payment(getAddress(mixNode), ".." + mixNode + " (Fake Mix)", totalPaymentAmount, false); fakeMixPayment.setType(Payment.Type.FAKE_MIX); @@ -842,9 +968,9 @@ public class Wallet extends Persistable implements Comparable { long costOfChangeAmt = getCostOfChange(noChangeFeeRate, longTermFeeRate); if(setChangeAmts.stream().allMatch(amt -> amt > costOfChangeAmt) || (numSets > 1 && differenceAmt / transaction.getVirtualSize() > noChangeFeeRate * 2)) { //Change output is required, determine new fee once change output has been added - WalletNode changeNode = getFreshNode(KeyPurpose.CHANGE); + WalletNode changeNode = getFreshNode(getChangeKeyPurpose()); while(txExcludedChangeNodes.contains(changeNode)) { - changeNode = getFreshNode(KeyPurpose.CHANGE, changeNode); + changeNode = getFreshNode(getChangeKeyPurpose(), changeNode); } TransactionOutput changeOutput = new TransactionOutput(transaction, setChangeAmts.iterator().next(), getOutputScript(changeNode)); double changeVSize = noChangeVSize + changeOutput.getLength() * numSets; @@ -860,7 +986,7 @@ public class Wallet extends Persistable implements Comparable { for(Long setChangeAmt : setChangeAmts) { transaction.addOutput(setChangeAmt, getOutputScript(changeNode)); changeMap.put(changeNode, setChangeAmt); - changeNode = getFreshNode(KeyPurpose.CHANGE, changeNode); + changeNode = getFreshNode(getChangeKeyPurpose(), changeNode); } if(setChangeAmts.stream().anyMatch(amt -> amt < costOfChangeAmt)) { @@ -958,7 +1084,9 @@ public class Wallet extends Persistable implements Comparable { total += selectedInputs.stream().mapToLong(BlockTransactionHashIndex::getValue).sum(); Map selectedInputsMap = new LinkedHashMap<>(); List shuffledInputs = new ArrayList<>(selectedInputs); - Collections.shuffle(shuffledInputs); + if(utxoSelector.shuffleInputs()) { + Collections.shuffle(shuffledInputs); + } for(BlockTransactionHashIndex shuffledInput : shuffledInputs) { selectedInputsMap.put(shuffledInput, utxos.get(shuffledInput)); } @@ -976,8 +1104,10 @@ public class Wallet extends Persistable implements Comparable { private List getGroupedUtxos(List utxoFilters, double feeRate, double longTermFeeRate, boolean groupByAddress, boolean includeSpentMempoolOutputs) { List outputGroups = new ArrayList<>(); - getGroupedUtxos(outputGroups, getNode(KeyPurpose.RECEIVE), utxoFilters, feeRate, longTermFeeRate, groupByAddress, includeSpentMempoolOutputs); - getGroupedUtxos(outputGroups, getNode(KeyPurpose.CHANGE), utxoFilters, feeRate, longTermFeeRate, groupByAddress, includeSpentMempoolOutputs); + for(KeyPurpose keyPurpose : getWalletKeyPurposes()) { + getGroupedUtxos(outputGroups, getNode(keyPurpose), utxoFilters, feeRate, longTermFeeRate, groupByAddress, includeSpentMempoolOutputs); + } + return outputGroups; } @@ -1527,9 +1657,9 @@ public class Wallet extends Persistable implements Comparable { return copy; } - public boolean containsPrivateKeys() { + public boolean containsMasterPrivateKeys() { for(Keystore keystore : keystores) { - if(keystore.hasPrivateKey()) { + if(keystore.hasMasterPrivateKey()) { return true; } } diff --git a/src/main/java/module-info.java b/src/main/java/module-info.java index 825652f..49bb37b 100644 --- a/src/main/java/module-info.java +++ b/src/main/java/module-info.java @@ -14,5 +14,6 @@ open module com.sparrowwallet.drongo { exports com.sparrowwallet.drongo.wallet; exports com.sparrowwallet.drongo.policy; exports com.sparrowwallet.drongo.uri; + exports com.sparrowwallet.drongo.bip47; exports org.bitcoin; } \ No newline at end of file diff --git a/src/test/java/com/sparrowwallet/drongo/OutputDescriptorTest.java b/src/test/java/com/sparrowwallet/drongo/OutputDescriptorTest.java index 4a5873a..8b603ac 100644 --- a/src/test/java/com/sparrowwallet/drongo/OutputDescriptorTest.java +++ b/src/test/java/com/sparrowwallet/drongo/OutputDescriptorTest.java @@ -47,7 +47,7 @@ public class OutputDescriptorTest { @Test public void masterP2PKH() { OutputDescriptor descriptor = OutputDescriptor.getOutputDescriptor("pkh([d34db33f/44'/0'/0']xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL/1/*)"); - Assert.assertEquals("pkh([d34db33f/44'/0'/0']xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL/1/*)", descriptor.toString()); + Assert.assertEquals("pkh([d34db33f/44h/0h/0h]xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL/1/*)", descriptor.toString()); ExtendedKey extendedPublicKey = descriptor.getSingletonExtendedPublicKey(); KeyDerivation derivation = descriptor.getKeyDerivation(extendedPublicKey); Assert.assertEquals("d34db33f", derivation.getMasterFingerprint()); @@ -58,7 +58,7 @@ public class OutputDescriptorTest { @Test public void singleP2SH_P2WPKH() { OutputDescriptor descriptor = OutputDescriptor.getOutputDescriptor("sh(wpkh([f09a3b29/49h/0h/0h]xpub6CjUWYtkq9KT1zkM5NPMxoJTCMm8JSFw7JPyMG6YLBzv5AsCTkASnsVyJhqL1aaqF5XSsFinHK3FDi8RoeEWcTG3DQA2TjqrZ6HJtatYbsU/0/*))"); - Assert.assertEquals("sh(wpkh([f09a3b29/49'/0'/0']xpub6CjUWYtkq9KT1zkM5NPMxoJTCMm8JSFw7JPyMG6YLBzv5AsCTkASnsVyJhqL1aaqF5XSsFinHK3FDi8RoeEWcTG3DQA2TjqrZ6HJtatYbsU/0/*))", descriptor.toString()); + Assert.assertEquals("sh(wpkh([f09a3b29/49h/0h/0h]xpub6CjUWYtkq9KT1zkM5NPMxoJTCMm8JSFw7JPyMG6YLBzv5AsCTkASnsVyJhqL1aaqF5XSsFinHK3FDi8RoeEWcTG3DQA2TjqrZ6HJtatYbsU/0/*))", descriptor.toString()); ExtendedKey extendedPublicKey = descriptor.getSingletonExtendedPublicKey(); KeyDerivation derivation = descriptor.getKeyDerivation(extendedPublicKey); Assert.assertEquals("f09a3b29", derivation.getMasterFingerprint()); @@ -95,7 +95,7 @@ public class OutputDescriptorTest { @Test public void testChecksum() { OutputDescriptor descriptor = OutputDescriptor.getOutputDescriptor("sh(multi(2,[00000000/111'/222]xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL,xpub68NZiKmJWnxxS6aaHmn81bvJeTESw724CRDs6HbuccFQN9Ku14VQrADWgqbhhTHBaohPX4CjNLf9fq9MYo6oDaPPLPxSb7gwQN3ih19Zm4Y/0))#tjg09x5t"); - Assert.assertEquals("sh(sortedmulti(2,[00000000/111'/222]xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL,xpub68NZiKmJWnxxS6aaHmn81bvJeTESw724CRDs6HbuccFQN9Ku14VQrADWgqbhhTHBaohPX4CjNLf9fq9MYo6oDaPPLPxSb7gwQN3ih19Zm4Y/0))#s66h0xn6", descriptor.toString(true)); + Assert.assertEquals("sh(sortedmulti(2,[00000000/111h/222]xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL,xpub68NZiKmJWnxxS6aaHmn81bvJeTESw724CRDs6HbuccFQN9Ku14VQrADWgqbhhTHBaohPX4CjNLf9fq9MYo6oDaPPLPxSb7gwQN3ih19Zm4Y/0))#vqfgjk5v", descriptor.toString(true)); } @Test(expected = IllegalArgumentException.class) diff --git a/src/test/java/com/sparrowwallet/drongo/bip47/PaymentCodeTest.java b/src/test/java/com/sparrowwallet/drongo/bip47/PaymentCodeTest.java new file mode 100644 index 0000000..e4cd501 --- /dev/null +++ b/src/test/java/com/sparrowwallet/drongo/bip47/PaymentCodeTest.java @@ -0,0 +1,171 @@ +package com.sparrowwallet.drongo.bip47; + +import com.sparrowwallet.drongo.KeyPurpose; +import com.sparrowwallet.drongo.Utils; +import com.sparrowwallet.drongo.address.Address; +import com.sparrowwallet.drongo.crypto.ChildNumber; +import com.sparrowwallet.drongo.crypto.DeterministicKey; +import com.sparrowwallet.drongo.crypto.DumpedPrivateKey; +import com.sparrowwallet.drongo.crypto.ECKey; +import com.sparrowwallet.drongo.policy.Policy; +import com.sparrowwallet.drongo.policy.PolicyType; +import com.sparrowwallet.drongo.protocol.*; +import com.sparrowwallet.drongo.wallet.*; +import org.junit.Assert; +import org.junit.Test; + +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import java.security.spec.InvalidKeySpecException; +import java.util.List; + +public class PaymentCodeTest { + @Test + public void testNotificationAddress() throws InvalidPaymentCodeException, InvalidKeySpecException, NoSuchAlgorithmException, InvalidKeyException, NoSuchProviderException, MnemonicException { + PaymentCode alicePaymentCode = new PaymentCode("PM8TJTLJbPRGxSbc8EJi42Wrr6QbNSaSSVJ5Y3E4pbCYiTHUskHg13935Ubb7q8tx9GVbh2UuRnBc3WSyJHhUrw8KhprKnn9eDznYGieTzFcwQRya4GA"); + Address aliceNotificationAddress = alicePaymentCode.getNotificationAddress(); + Assert.assertEquals("1JDdmqFLhpzcUwPeinhJbUPw4Co3aWLyzW", aliceNotificationAddress.toString()); + + ECKey alicePrivKey = DumpedPrivateKey.fromBase58("Kx983SRhAZpAhj7Aac1wUXMJ6XZeyJKqCxJJ49dxEbYCT4a1ozRD").getKey(); + + byte[] alicePayload = alicePaymentCode.getPayload(); + Assert.assertEquals("010002b85034fb08a8bfefd22848238257b252721454bbbfba2c3667f168837ea2cdad671af9f65904632e2dcc0c6ad314e11d53fc82fa4c4ea27a4a14eccecc478fee00000000000000000000000000", Utils.bytesToHex(alicePayload)); + + PaymentCode paymentCodeBob = new PaymentCode("PM8TJS2JxQ5ztXUpBBRnpTbcUXbUHy2T1abfrb3KkAAtMEGNbey4oumH7Hc578WgQJhPjBxteQ5GHHToTYHE3A1w6p7tU6KSoFmWBVbFGjKPisZDbP97"); + ECKey bobNotificationPubKey = paymentCodeBob.getNotificationKey(); + Assert.assertEquals("024ce8e3b04ea205ff49f529950616c3db615b1e37753858cc60c1ce64d17e2ad8", Utils.bytesToHex(bobNotificationPubKey.getPubKey())); + + TransactionOutPoint transactionOutPoint = new TransactionOutPoint(Sha256Hash.wrapReversed(Utils.hexToBytes("86f411ab1c8e70ae8a0795ab7a6757aea6e4d5ae1826fc7b8f00c597d500609c")), 1); + Assert.assertEquals("86f411ab1c8e70ae8a0795ab7a6757aea6e4d5ae1826fc7b8f00c597d500609c01000000", Utils.bytesToHex(transactionOutPoint.bitcoinSerialize())); + + SecretPoint secretPoint = new SecretPoint(alicePrivKey.getPrivKeyBytes(), bobNotificationPubKey.getPubKey()); + Assert.assertEquals("736a25d9250238ad64ed5da03450c6a3f4f8f4dcdf0b58d1ed69029d76ead48d", Utils.bytesToHex(secretPoint.ECDHSecretAsBytes())); + + byte[] blindingMask = PaymentCode.getMask(secretPoint.ECDHSecretAsBytes(), transactionOutPoint.bitcoinSerialize()); + Assert.assertEquals("be6e7a4256cac6f4d4ed4639b8c39c4cb8bece40010908e70d17ea9d77b4dc57f1da36f2d6641ccb37cf2b9f3146686462e0fa3161ae74f88c0afd4e307adbd5", Utils.bytesToHex(blindingMask)); + + byte[] blindedPaymentCode = PaymentCode.blind(alicePayload, blindingMask); + Assert.assertEquals("010002063e4eb95e62791b06c50e1a3a942e1ecaaa9afbbeb324d16ae6821e091611fa96c0cf048f607fe51a0327f5e2528979311c78cb2de0d682c61e1180fc3d543b00000000000000000000000000", Utils.bytesToHex(blindedPaymentCode)); + + Transaction transaction = new Transaction(); + List inputChunks = List.of(ScriptChunk.fromData(Utils.hexToBytes("3045022100ac8c6dbc482c79e86c18928a8b364923c774bfdbd852059f6b3778f2319b59a7022029d7cc5724e2f41ab1fcfc0ba5a0d4f57ca76f72f19530ba97c860c70a6bf0a801")), ScriptChunk.fromData(alicePrivKey.getPubKey())); + transaction.addInput(transactionOutPoint.getHash(), transactionOutPoint.getIndex(), new Script(inputChunks)); + transaction.addOutput(10000, paymentCodeBob.getNotificationAddress()); + List opReturnChunks = List.of(ScriptChunk.fromOpcode(ScriptOpCodes.OP_RETURN), ScriptChunk.fromData(blindedPaymentCode)); + transaction.addOutput(10000, new Script(opReturnChunks)); + Assert.assertEquals("010000000186f411ab1c8e70ae8a0795ab7a6757aea6e4d5ae1826fc7b8f00c597d500609c010000006b483045022100ac8c6dbc482c79e86c18928a8b364923c774bfdb" + + "d852059f6b3778f2319b59a7022029d7cc5724e2f41ab1fcfc0ba5a0d4f57ca76f72f19530ba97c860c70a6bf0a801210272d83d8a1fa323feab1c085157a0791b46eba34afb8bfbfaeb3a3fcc3f2" + + "c9ad8ffffffff0210270000000000001976a9148066a8e7ee82e5c5b9b7dc1765038340dc5420a988ac1027000000000000536a4c50010002063e4eb95e62791b06c50e1a3a942e1ecaaa9afbbeb3" + + "24d16ae6821e091611fa96c0cf048f607fe51a0327f5e2528979311c78cb2de0d682c61e1180fc3d543b0000000000000000000000000000000000", Utils.bytesToHex(transaction.bitcoinSerialize())); + Assert.assertEquals("9414f1681fb1255bd168a806254321a837008dd4480c02226063183deb100204", transaction.getTxId().toString()); + + ECKey alicePubKey = ECKey.fromPublicOnly(transaction.getInputs().get(0).getScriptSig().getChunks().get(1).data); + Assert.assertArrayEquals(alicePubKey.getPubKey(), alicePrivKey.getPubKey()); + + DeterministicSeed bobSeed = new DeterministicSeed("reward upper indicate eight swift arch injury crystal super wrestle already dentist", "", 0, DeterministicSeed.Type.BIP39); + Keystore bobKeystore = Keystore.fromSeed(bobSeed, List.of(new ChildNumber(47, true), ChildNumber.ZERO_HARDENED, ChildNumber.ZERO_HARDENED)); + ECKey bobNotificationPrivKey = bobKeystore.getBip47ExtendedPrivateKey().getKey(List.of(ChildNumber.ZERO_HARDENED, new ChildNumber(0))); + + SecretPoint bobSecretPoint = new SecretPoint(bobNotificationPrivKey.getPrivKeyBytes(), alicePubKey.getPubKey()); + Assert.assertEquals("736a25d9250238ad64ed5da03450c6a3f4f8f4dcdf0b58d1ed69029d76ead48d", Utils.bytesToHex(bobSecretPoint.ECDHSecretAsBytes())); + + byte[] bobBlindingMask = PaymentCode.getMask(secretPoint.ECDHSecretAsBytes(), transaction.getInputs().get(0).getOutpoint().bitcoinSerialize()); + Assert.assertEquals("be6e7a4256cac6f4d4ed4639b8c39c4cb8bece40010908e70d17ea9d77b4dc57f1da36f2d6641ccb37cf2b9f3146686462e0fa3161ae74f88c0afd4e307adbd5", Utils.bytesToHex(bobBlindingMask)); + + PaymentCode unblindedPaymentCode = new PaymentCode(PaymentCode.blind(transaction.getOutputs().get(1).getScript().getChunks().get(1).data, blindingMask)); + Assert.assertEquals(alicePaymentCode, unblindedPaymentCode); + + PaymentCode unblindedPaymentCode2 = PaymentCode.getPaymentCode(transaction, bobKeystore); + Assert.assertEquals(alicePaymentCode, unblindedPaymentCode2); + } + + @Test + public void testFromSeed() throws MnemonicException { + DeterministicSeed aliceSeed = new DeterministicSeed("response seminar brave tip suit recall often sound stick owner lottery motion", "", 0, DeterministicSeed.Type.BIP39); + Keystore aliceKeystore = Keystore.fromSeed(aliceSeed, List.of(new ChildNumber(47, true), ChildNumber.ZERO_HARDENED, ChildNumber.ZERO_HARDENED)); + + DeterministicKey bip47PubKey = aliceKeystore.getExtendedPublicKey().getKey(); + PaymentCode alicePaymentCode = new PaymentCode(bip47PubKey.getPubKey(), bip47PubKey.getChainCode()); + Assert.assertEquals("PM8TJTLJbPRGxSbc8EJi42Wrr6QbNSaSSVJ5Y3E4pbCYiTHUskHg13935Ubb7q8tx9GVbh2UuRnBc3WSyJHhUrw8KhprKnn9eDznYGieTzFcwQRya4GA", alicePaymentCode.toString()); + } + + @Test + public void testPaymentAddress() throws MnemonicException, InvalidPaymentCodeException, NoSuchAlgorithmException, InvalidKeySpecException, InvalidKeyException, NoSuchProviderException, NotSecp256k1Exception { + DeterministicSeed seed = new DeterministicSeed("response seminar brave tip suit recall often sound stick owner lottery motion", "", 0, DeterministicSeed.Type.BIP39); + Keystore keystore = Keystore.fromSeed(seed, List.of(new ChildNumber(47, true), ChildNumber.ZERO_HARDENED, ChildNumber.ZERO_HARDENED)); + DeterministicKey privateKey = keystore.getExtendedPrivateKey().getKey(List.of(ChildNumber.ZERO_HARDENED, ChildNumber.ZERO)); + + PaymentCode paymentCodeBob = new PaymentCode("PM8TJS2JxQ5ztXUpBBRnpTbcUXbUHy2T1abfrb3KkAAtMEGNbey4oumH7Hc578WgQJhPjBxteQ5GHHToTYHE3A1w6p7tU6KSoFmWBVbFGjKPisZDbP97"); + + PaymentAddress paymentAddress0 = new PaymentAddress(paymentCodeBob, 0, privateKey.getPrivKeyBytes()); + ECKey sendKey0 = paymentAddress0.getSendECKey(); + Assert.assertEquals("141fi7TY3h936vRUKh1qfUZr8rSBuYbVBK", ScriptType.P2PKH.getAddress(sendKey0).toString()); + + PaymentAddress paymentAddress1 = new PaymentAddress(paymentCodeBob, 1, privateKey.getPrivKeyBytes()); + ECKey sendKey1 = paymentAddress1.getSendECKey(); + Assert.assertEquals("12u3Uued2fuko2nY4SoSFGCoGLCBUGPkk6", ScriptType.P2PKH.getAddress(sendKey1).toString()); + } + + @Test + public void testChildWallet() throws MnemonicException, InvalidPaymentCodeException { + DeterministicSeed aliceSeed = new DeterministicSeed("response seminar brave tip suit recall often sound stick owner lottery motion", "", 0, DeterministicSeed.Type.BIP39); + Wallet aliceWallet = new Wallet(); + aliceWallet.setPolicyType(PolicyType.SINGLE); + aliceWallet.setScriptType(ScriptType.P2PKH); + aliceWallet.getKeystores().add(Keystore.fromSeed(aliceSeed, aliceWallet.getScriptType().getDefaultDerivation())); + aliceWallet.setDefaultPolicy(Policy.getPolicy(PolicyType.SINGLE, ScriptType.P2PKH, aliceWallet.getKeystores(), 1)); + + PaymentCode paymentCodeBob = new PaymentCode("PM8TJS2JxQ5ztXUpBBRnpTbcUXbUHy2T1abfrb3KkAAtMEGNbey4oumH7Hc578WgQJhPjBxteQ5GHHToTYHE3A1w6p7tU6KSoFmWBVbFGjKPisZDbP97"); + + Wallet aliceBip47Wallet = aliceWallet.addChildWallet(paymentCodeBob, ScriptType.P2PKH); + PaymentCode paymentCodeAlice = aliceBip47Wallet.getKeystores().get(0).getPaymentCode(); + + Assert.assertEquals(aliceWallet.getPaymentCode(), aliceBip47Wallet.getPaymentCode()); + Assert.assertEquals("PM8TJTLJbPRGxSbc8EJi42Wrr6QbNSaSSVJ5Y3E4pbCYiTHUskHg13935Ubb7q8tx9GVbh2UuRnBc3WSyJHhUrw8KhprKnn9eDznYGieTzFcwQRya4GA", paymentCodeAlice.toString()); + Assert.assertEquals("1JDdmqFLhpzcUwPeinhJbUPw4Co3aWLyzW", paymentCodeAlice.getNotificationAddress().toString()); + + WalletNode sendNode0 = aliceBip47Wallet.getFreshNode(KeyPurpose.SEND); + Address address0 = aliceBip47Wallet.getAddress(sendNode0); + Assert.assertEquals("141fi7TY3h936vRUKh1qfUZr8rSBuYbVBK", address0.toString()); + + WalletNode sendNode1 = aliceBip47Wallet.getFreshNode(KeyPurpose.SEND, sendNode0); + Address address1 = aliceBip47Wallet.getAddress(sendNode1); + Assert.assertEquals("12u3Uued2fuko2nY4SoSFGCoGLCBUGPkk6", address1.toString()); + + WalletNode sendNode2 = aliceBip47Wallet.getFreshNode(KeyPurpose.SEND, sendNode1); + Address address2 = aliceBip47Wallet.getAddress(sendNode2); + Assert.assertEquals("1FsBVhT5dQutGwaPePTYMe5qvYqqjxyftc", address2.toString()); + + DeterministicSeed bobSeed = new DeterministicSeed("reward upper indicate eight swift arch injury crystal super wrestle already dentist", "", 0, DeterministicSeed.Type.BIP39); + Wallet bobWallet = new Wallet(); + bobWallet.setPolicyType(PolicyType.SINGLE); + bobWallet.setScriptType(ScriptType.P2PKH); + bobWallet.getKeystores().add(Keystore.fromSeed(bobSeed, bobWallet.getScriptType().getDefaultDerivation())); + bobWallet.setDefaultPolicy(Policy.getPolicy(PolicyType.SINGLE, ScriptType.P2PKH, bobWallet.getKeystores(), 1)); + + Wallet bobBip47Wallet = bobWallet.addChildWallet(paymentCodeAlice, ScriptType.P2PKH); + Assert.assertEquals(paymentCodeBob.toString(), bobBip47Wallet.getKeystores().get(0).getPaymentCode().toString()); + Assert.assertEquals("1ChvUUvht2hUQufHBXF8NgLhW8SwE2ecGV", paymentCodeBob.getNotificationAddress().toString()); + + WalletNode receiveNode0 = bobBip47Wallet.getFreshNode(KeyPurpose.RECEIVE); + Address receiveAddress0 = bobBip47Wallet.getAddress(receiveNode0); + Assert.assertEquals("141fi7TY3h936vRUKh1qfUZr8rSBuYbVBK", receiveAddress0.toString()); + + WalletNode receiveNode1 = bobBip47Wallet.getFreshNode(KeyPurpose.RECEIVE, receiveNode0); + Address receiveAddress1 = bobBip47Wallet.getAddress(receiveNode1); + Assert.assertEquals("12u3Uued2fuko2nY4SoSFGCoGLCBUGPkk6", receiveAddress1.toString()); + + WalletNode receiveNode2 = bobBip47Wallet.getFreshNode(KeyPurpose.RECEIVE, receiveNode1); + Address receiveAddress2 = bobBip47Wallet.getAddress(receiveNode2); + Assert.assertEquals("1FsBVhT5dQutGwaPePTYMe5qvYqqjxyftc", receiveAddress2.toString()); + + ECKey privKey0 = bobWallet.getKeystores().get(0).getKey(receiveNode0); + ECKey pubKey0 = bobWallet.getKeystores().get(0).getPubKey(receiveNode0); + Assert.assertArrayEquals(privKey0.getPubKey(), pubKey0.getPubKey()); + + ECKey privKey1 = bobWallet.getKeystores().get(0).getKey(receiveNode1); + ECKey pubKey1 = bobWallet.getKeystores().get(0).getPubKey(receiveNode1); + Assert.assertArrayEquals(privKey1.getPubKey(), pubKey1.getPubKey()); + } +} diff --git a/src/test/java/com/sparrowwallet/drongo/psbt/PSBTTest.java b/src/test/java/com/sparrowwallet/drongo/psbt/PSBTTest.java index 930f7b3..dd9ff2f 100644 --- a/src/test/java/com/sparrowwallet/drongo/psbt/PSBTTest.java +++ b/src/test/java/com/sparrowwallet/drongo/psbt/PSBTTest.java @@ -19,12 +19,6 @@ public class PSBTTest { PSBT.fromString(psbt); } - @Test(expected = PSBTParseException.class) - public void missingOutputs() throws PSBTParseException { - String psbt = "cHNidP8BAHUCAAAAASaBcTce3/KF6Tet7qSze3gADAVmy7OtZGQXE8pCFxv2AAAAAAD+////AtPf9QUAAAAAGXapFNDFmQPFusKGh2DpD9UhpGZap2UgiKwA4fUFAAAAABepFDVF5uM7gyxHBQ8k0+65PJwDlIvHh7MuEwAAAQD9pQEBAAAAAAECiaPHHqtNIOA3G7ukzGmPopXJRjr6Ljl/hTPMti+VZ+UBAAAAFxYAFL4Y0VKpsBIDna89p95PUzSe7LmF/////4b4qkOnHf8USIk6UwpyN+9rRgi7st0tAXHmOuxqSJC0AQAAABcWABT+Pp7xp0XpdNkCxDVZQ6vLNL1TU/////8CAMLrCwAAAAAZdqkUhc/xCX/Z4Ai7NK9wnGIZeziXikiIrHL++E4sAAAAF6kUM5cluiHv1irHU6m80GfWx6ajnQWHAkcwRAIgJxK+IuAnDzlPVoMR3HyppolwuAJf3TskAinwf4pfOiQCIAGLONfc0xTnNMkna9b7QPZzMlvEuqFEyADS8vAtsnZcASED0uFWdJQbrUqZY3LLh+GFbTZSYG2YVi/jnF6efkE/IQUCSDBFAiEA0SuFLYXc2WHS9fSrZgZU327tzHlMDDPOXMMJ/7X85Y0CIGczio4OFyXBl/saiK9Z9R5E5CVbIBZ8hoQDHAXR8lkqASECI7cr7vCWXRC+B3jv7NYfysb3mk6haTkzgHNEZPhPKrMAAAAAAA=="; - PSBT.fromString(psbt); - } - @Test(expected = PSBTParseException.class) public void unsignedTxWithScriptSig() throws PSBTParseException { String psbt = "cHNidP8BAP0KAQIAAAACqwlJoIxa98SbghL0F+LxWrP1wz3PFTghqBOfh3pbe+QAAAAAakcwRAIgR1lmF5fAGwNrJZKJSGhiGDR9iYZLcZ4ff89X0eURZYcCIFMJ6r9Wqk2Ikf/REf3xM286KdqGbX+EhtdVRs7tr5MZASEDXNxh/HupccC1AaZGoqg7ECy0OIEhfKaC3Ibi1z+ogpL+////qwlJoIxa98SbghL0F+LxWrP1wz3PFTghqBOfh3pbe+QBAAAAAP7///8CYDvqCwAAAAAZdqkUdopAu9dAy+gdmI5x3ipNXHE5ax2IrI4kAAAAAAAAGXapFG9GILVT+glechue4O/p+gOcykWXiKwAAAAAAAABASAA4fUFAAAAABepFDVF5uM7gyxHBQ8k0+65PJwDlIvHhwEEFgAUhdE1N/LiZUBaNNuvqePdoB+4IwgAAAA="; diff --git a/src/test/java/com/sparrowwallet/drongo/wallet/WalletTest.java b/src/test/java/com/sparrowwallet/drongo/wallet/WalletTest.java index 92804b8..d9f23e1 100644 --- a/src/test/java/com/sparrowwallet/drongo/wallet/WalletTest.java +++ b/src/test/java/com/sparrowwallet/drongo/wallet/WalletTest.java @@ -104,8 +104,8 @@ public class WalletTest { wallet.getKeystores().add(keystore); wallet.setDefaultPolicy(Policy.getPolicy(PolicyType.SINGLE, ScriptType.P2PKH, wallet.getKeystores(), 1)); - Assert.assertEquals("12kTQjuWDp7Uu6PwY6CsS1KLTt3d1DBHZa", wallet.getAddress(KeyPurpose.RECEIVE, 0).toString()); - Assert.assertEquals("1HbQwQCitHQxVtP39isXmUdHx7hQCZovrK", wallet.getAddress(KeyPurpose.RECEIVE, 1).toString()); + Assert.assertEquals("12kTQjuWDp7Uu6PwY6CsS1KLTt3d1DBHZa", wallet.getAddress(new WalletNode(KeyPurpose.RECEIVE, 0)).toString()); + Assert.assertEquals("1HbQwQCitHQxVtP39isXmUdHx7hQCZovrK", wallet.getAddress(new WalletNode(KeyPurpose.RECEIVE, 1)).toString()); } @Test @@ -119,8 +119,8 @@ public class WalletTest { wallet.getKeystores().add(keystore); wallet.setDefaultPolicy(Policy.getPolicy(PolicyType.SINGLE, ScriptType.P2SH_P2WPKH, wallet.getKeystores(), 1)); - Assert.assertEquals("3NZLE4TntsjtcZ5MbrfxwtYo9meBVybVQj", wallet.getAddress(KeyPurpose.RECEIVE, 0).toString()); - Assert.assertEquals("32YBBuRsp8XTeLx4T6BmD2L4nANGaNDkSg", wallet.getAddress(KeyPurpose.RECEIVE, 1).toString()); + Assert.assertEquals("3NZLE4TntsjtcZ5MbrfxwtYo9meBVybVQj", wallet.getAddress(new WalletNode(KeyPurpose.RECEIVE, 0)).toString()); + Assert.assertEquals("32YBBuRsp8XTeLx4T6BmD2L4nANGaNDkSg", wallet.getAddress(new WalletNode(KeyPurpose.RECEIVE, 1)).toString()); } @Test @@ -134,8 +134,8 @@ public class WalletTest { wallet.getKeystores().add(keystore); wallet.setDefaultPolicy(Policy.getPolicy(PolicyType.SINGLE, ScriptType.P2WPKH, wallet.getKeystores(), 1)); - Assert.assertEquals("bc1quvxdut936uswuxwxrk6nvjmgwxh463r0fjwn55", wallet.getAddress(KeyPurpose.RECEIVE, 0).toString()); - Assert.assertEquals("bc1q95j2862dz7mqpraw6qdjc70gumyu5z7adgq9x9", wallet.getAddress(KeyPurpose.RECEIVE, 1).toString()); + Assert.assertEquals("bc1quvxdut936uswuxwxrk6nvjmgwxh463r0fjwn55", wallet.getAddress(new WalletNode(KeyPurpose.RECEIVE, 0)).toString()); + Assert.assertEquals("bc1q95j2862dz7mqpraw6qdjc70gumyu5z7adgq9x9", wallet.getAddress(new WalletNode(KeyPurpose.RECEIVE, 1)).toString()); } @Test @@ -159,8 +159,8 @@ public class WalletTest { wallet.getKeystores().add(keystore2); wallet.setDefaultPolicy(Policy.getPolicy(PolicyType.MULTI, ScriptType.P2SH, wallet.getKeystores(), 2)); - Assert.assertEquals("38kq6yz4VcYymTExQPY3gppbz38mtPLveK", wallet.getAddress(KeyPurpose.RECEIVE, 0).toString()); - Assert.assertEquals("3EdKaNsnjBTBggWcSMRyVju6GbHWy68mAH", wallet.getAddress(KeyPurpose.CHANGE, 1).toString()); + Assert.assertEquals("38kq6yz4VcYymTExQPY3gppbz38mtPLveK", wallet.getAddress(new WalletNode(KeyPurpose.RECEIVE, 0)).toString()); + Assert.assertEquals("3EdKaNsnjBTBggWcSMRyVju6GbHWy68mAH", wallet.getAddress(new WalletNode(KeyPurpose.CHANGE, 1)).toString()); } @Test @@ -184,8 +184,8 @@ public class WalletTest { wallet.getKeystores().add(keystore2); wallet.setDefaultPolicy(Policy.getPolicy(PolicyType.MULTI, ScriptType.P2SH_P2WSH, wallet.getKeystores(), 2)); - Assert.assertEquals("3Mw8xqAHh8g3eBvh7q1UEUmoexqdXDK9Tf", wallet.getAddress(KeyPurpose.RECEIVE, 0).toString()); - Assert.assertEquals("35dFo1ivJ8jyHpyf42MWvnYf5LBU8Siren", wallet.getAddress(KeyPurpose.CHANGE, 1).toString()); + Assert.assertEquals("3Mw8xqAHh8g3eBvh7q1UEUmoexqdXDK9Tf", wallet.getAddress(new WalletNode(KeyPurpose.RECEIVE, 0)).toString()); + Assert.assertEquals("35dFo1ivJ8jyHpyf42MWvnYf5LBU8Siren", wallet.getAddress(new WalletNode(KeyPurpose.CHANGE, 1)).toString()); } @Test @@ -209,8 +209,8 @@ public class WalletTest { wallet.getKeystores().add(keystore2); wallet.setDefaultPolicy(Policy.getPolicy(PolicyType.MULTI, ScriptType.P2WSH, wallet.getKeystores(), 2)); - Assert.assertEquals("bc1q20e4vm656h5lvmngz9ztz6hjzftvh39yzngqhuqzk8qzj7tqnzaqgclrwc", wallet.getAddress(KeyPurpose.RECEIVE, 0).toString()); - Assert.assertEquals("bc1q2epdx7dplwaas2jucfrzmxm8350rqh68hs6vqreysku80ye44mfqla85f2", wallet.getAddress(KeyPurpose.CHANGE, 1).toString()); + Assert.assertEquals("bc1q20e4vm656h5lvmngz9ztz6hjzftvh39yzngqhuqzk8qzj7tqnzaqgclrwc", wallet.getAddress(new WalletNode(KeyPurpose.RECEIVE, 0)).toString()); + Assert.assertEquals("bc1q2epdx7dplwaas2jucfrzmxm8350rqh68hs6vqreysku80ye44mfqla85f2", wallet.getAddress(new WalletNode(KeyPurpose.CHANGE, 1)).toString()); } @Test @@ -227,6 +227,6 @@ public class WalletTest { List derivation = List.of(keystore.getExtendedPublicKey().getKeyChildNumber(), new ChildNumber(0)); Assert.assertEquals("027ecc656f4b91b92881b6f07cf876cd2e42b20df7acc4df54fc3315fbb2d13e1c", Utils.bytesToHex(extendedKey.getKey(derivation).getPubKey())); - Assert.assertEquals("bc1qarzeu6ncapyvjzdeayjq8vnzp6uvcn4eaeuuqq", wallet.getAddress(KeyPurpose.RECEIVE, 0).toString()); + Assert.assertEquals("bc1qarzeu6ncapyvjzdeayjq8vnzp6uvcn4eaeuuqq", wallet.getAddress(new WalletNode(KeyPurpose.RECEIVE, 0)).toString()); } } From 956f59880e508127b62d62022e3e2618f659f4d2 Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Wed, 23 Feb 2022 09:44:09 +0200 Subject: [PATCH 105/155] fix for retreiving notification tx data for non-zero bip47 accounts --- src/main/java/com/sparrowwallet/drongo/bip47/PaymentCode.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/sparrowwallet/drongo/bip47/PaymentCode.java b/src/main/java/com/sparrowwallet/drongo/bip47/PaymentCode.java index ea881e0..2cd9579 100644 --- a/src/main/java/com/sparrowwallet/drongo/bip47/PaymentCode.java +++ b/src/main/java/com/sparrowwallet/drongo/bip47/PaymentCode.java @@ -112,7 +112,9 @@ public class PaymentCode { TransactionInput txInput = getDesignatedInput(transaction); ECKey pubKey = getDesignatedPubKey(txInput); - ECKey notificationPrivKey = keystore.getBip47ExtendedPrivateKey().getKey(List.of(ChildNumber.ZERO_HARDENED, new ChildNumber(0))); + List derivation = keystore.getKeyDerivation().getDerivation(); + ChildNumber derivationStart = derivation.isEmpty() ? ChildNumber.ZERO_HARDENED : derivation.get(derivation.size() - 1); + ECKey notificationPrivKey = keystore.getBip47ExtendedPrivateKey().getKey(List.of(derivationStart, new ChildNumber(0))); SecretPoint secretPoint = new SecretPoint(notificationPrivKey.getPrivKeyBytes(), pubKey.getPubKey()); byte[] blindingMask = getMask(secretPoint.ECDHSecretAsBytes(), txInput.getOutpoint().bitcoinSerialize()); byte[] blindedPaymentCode = getOpReturnData(transaction); From 0734757a177627600a63cb3347804ea126b0d417 Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Wed, 2 Mar 2022 13:34:10 +0200 Subject: [PATCH 106/155] support nested wallets --- .../drongo/bip47/PaymentCode.java | 4 + .../com/sparrowwallet/drongo/psbt/PSBT.java | 26 +- .../sparrowwallet/drongo/psbt/PSBTInput.java | 6 +- .../drongo/wallet/CoinbaseUtxoFilter.java | 2 +- .../drongo/wallet/OutputGroup.java | 10 +- .../drongo/wallet/StonewallUtxoSelector.java | 16 +- .../sparrowwallet/drongo/wallet/Wallet.java | 266 ++++++++++++++---- .../drongo/wallet/WalletNode.java | 74 ++++- .../drongo/wallet/WalletTransaction.java | 2 +- .../drongo/bip47/PaymentCodeTest.java | 12 +- .../drongo/crypto/ECKeyTest.java | 2 +- .../drongo/wallet/WalletTest.java | 39 ++- 12 files changed, 352 insertions(+), 107 deletions(-) diff --git a/src/main/java/com/sparrowwallet/drongo/bip47/PaymentCode.java b/src/main/java/com/sparrowwallet/drongo/bip47/PaymentCode.java index 2cd9579..c2a2966 100644 --- a/src/main/java/com/sparrowwallet/drongo/bip47/PaymentCode.java +++ b/src/main/java/com/sparrowwallet/drongo/bip47/PaymentCode.java @@ -361,6 +361,10 @@ public class PaymentCode { return new PaymentCode(strPaymentCode, pubkey, chain); } + public String toAbbreviatedString() { + return strPaymentCode.substring(0, 8) + "..." + strPaymentCode.substring(strPaymentCode.length() - 3); + } + @Override public boolean equals(Object o) { if(this == o) { diff --git a/src/main/java/com/sparrowwallet/drongo/psbt/PSBT.java b/src/main/java/com/sparrowwallet/drongo/psbt/PSBT.java index 51c6f39..cf97b56 100644 --- a/src/main/java/com/sparrowwallet/drongo/psbt/PSBT.java +++ b/src/main/java/com/sparrowwallet/drongo/psbt/PSBT.java @@ -18,6 +18,7 @@ import java.util.*; import static com.sparrowwallet.drongo.psbt.PSBTEntry.*; import static com.sparrowwallet.drongo.psbt.PSBTInput.*; import static com.sparrowwallet.drongo.psbt.PSBTOutput.*; +import static com.sparrowwallet.drongo.wallet.Wallet.addDummySpendingInput; public class PSBT { public static final byte PSBT_GLOBAL_UNSIGNED_TX = 0x00; @@ -89,12 +90,16 @@ public class PSBT { this.version = version; } - boolean alwaysIncludeWitnessUtxo = wallet.getKeystores().stream().anyMatch(keystore -> keystore.getWalletModel().alwaysIncludeNonWitnessUtxo()); - int inputIndex = 0; for(Iterator> iter = walletTransaction.getSelectedUtxos().entrySet().iterator(); iter.hasNext(); inputIndex++) { Map.Entry utxoEntry = iter.next(); - Transaction utxo = wallet.getTransactions().get(utxoEntry.getKey().getHash()).getTransaction(); + + WalletNode walletNode = utxoEntry.getValue(); + Wallet signingWallet = walletNode.getWallet(); + + boolean alwaysIncludeWitnessUtxo = signingWallet.getKeystores().stream().anyMatch(keystore -> keystore.getWalletModel().alwaysIncludeNonWitnessUtxo()); + + Transaction utxo = signingWallet.getTransactions().get(utxoEntry.getKey().getHash()).getTransaction(); int utxoIndex = (int)utxoEntry.getKey().getIndex(); TransactionOutput utxoOutput = utxo.getOutputs().get(utxoIndex); @@ -112,17 +117,16 @@ public class PSBT { Map derivedPublicKeys = new LinkedHashMap<>(); ECKey tapInternalKey = null; - for(Keystore keystore : wallet.getKeystores()) { - WalletNode walletNode = utxoEntry.getValue(); - derivedPublicKeys.put(wallet.getScriptType().getOutputKey(keystore.getPubKey(walletNode)), keystore.getKeyDerivation().extend(walletNode.getDerivation())); + for(Keystore keystore : signingWallet.getKeystores()) { + derivedPublicKeys.put(signingWallet.getScriptType().getOutputKey(keystore.getPubKey(walletNode)), keystore.getKeyDerivation().extend(walletNode.getDerivation())); //TODO: Implement Musig for multisig wallets - if(wallet.getScriptType() == ScriptType.P2TR) { + if(signingWallet.getScriptType() == ScriptType.P2TR) { tapInternalKey = keystore.getPubKey(walletNode); } } - PSBTInput psbtInput = new PSBTInput(this, wallet.getScriptType(), transaction, inputIndex, utxo, utxoIndex, redeemScript, witnessScript, derivedPublicKeys, Collections.emptyMap(), tapInternalKey, alwaysIncludeWitnessUtxo); + PSBTInput psbtInput = new PSBTInput(this, signingWallet.getScriptType(), transaction, inputIndex, utxo, utxoIndex, redeemScript, witnessScript, derivedPublicKeys, Collections.emptyMap(), tapInternalKey, alwaysIncludeWitnessUtxo); psbtInputs.add(psbtInput); } @@ -132,7 +136,7 @@ public class PSBT { Address address = txOutput.getScript().getToAddresses()[0]; if(walletTransaction.getPayments().stream().anyMatch(payment -> payment.getAddress().equals(address))) { outputNodes.add(wallet.getWalletAddresses().getOrDefault(address, null)); - } else if(walletTransaction.getChangeMap().keySet().stream().anyMatch(changeNode -> wallet.getAddress(changeNode).equals(address))) { + } else if(walletTransaction.getChangeMap().keySet().stream().anyMatch(changeNode -> changeNode.getAddress().equals(address))) { outputNodes.add(wallet.getWalletAddresses().getOrDefault(address, null)); } } catch(NonStandardScriptException e) { @@ -151,7 +155,7 @@ public class PSBT { //Construct dummy transaction to spend the UTXO created by this wallet's txOutput Transaction transaction = new Transaction(); - TransactionInput spendingInput = wallet.addDummySpendingInput(transaction, outputNode, txOutput); + TransactionInput spendingInput = addDummySpendingInput(transaction, outputNode, txOutput); Script redeemScript = null; if(ScriptType.P2SH.isScriptType(txOutput.getScript())) { @@ -164,7 +168,7 @@ public class PSBT { } Map derivedPublicKeys = new LinkedHashMap<>(); - for(Keystore keystore : wallet.getKeystores()) { + for(Keystore keystore : outputNode.getWallet().getKeystores()) { derivedPublicKeys.put(keystore.getPubKey(outputNode), keystore.getKeyDerivation().extend(outputNode.getDerivation())); } diff --git a/src/main/java/com/sparrowwallet/drongo/psbt/PSBTInput.java b/src/main/java/com/sparrowwallet/drongo/psbt/PSBTInput.java index 4d89317..7b67a63 100644 --- a/src/main/java/com/sparrowwallet/drongo/psbt/PSBTInput.java +++ b/src/main/java/com/sparrowwallet/drongo/psbt/PSBTInput.java @@ -102,11 +102,7 @@ public class PSBTInput { log.debug(" Transaction input references txid: " + input.getOutpoint().getHash() + " vout " + input.getOutpoint().getIndex() + " with script " + input.getScriptSig()); } for(TransactionOutput output: nonWitnessTx.getOutputs()) { - try { - log.debug(" Transaction output value: " + output.getValue() + " to addresses " + Arrays.asList(output.getScript().getToAddresses()) + " with script hex " + Utils.bytesToHex(output.getScript().getProgram()) + " to script " + output.getScript()); - } catch(NonStandardScriptException e) { - log.error("Unknown script type", e); - } + log.debug(" Transaction output value: " + output.getValue() + (output.getScript().getToAddress() != null ? " to address " + output.getScript().getToAddress() : "") + " with script hex " + Utils.bytesToHex(output.getScript().getProgram()) + " to script " + output.getScript()); } break; case PSBT_IN_WITNESS_UTXO: diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/CoinbaseUtxoFilter.java b/src/main/java/com/sparrowwallet/drongo/wallet/CoinbaseUtxoFilter.java index 92051c8..8f079f6 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/CoinbaseUtxoFilter.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/CoinbaseUtxoFilter.java @@ -12,7 +12,7 @@ public class CoinbaseUtxoFilter implements UtxoFilter { @Override public boolean isEligible(BlockTransactionHashIndex candidate) { //Disallow immature coinbase outputs - BlockTransaction blockTransaction = wallet.getTransactions().get(candidate.getHash()); + BlockTransaction blockTransaction = wallet.getWalletTransaction(candidate.getHash()); if(blockTransaction != null && blockTransaction.getTransaction() != null && blockTransaction.getTransaction().isCoinBase() && wallet.getStoredBlockHeight() != null && candidate.getConfirmations(wallet.getStoredBlockHeight()) < Transaction.COINBASE_MATURITY_THRESHOLD) { return false; diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/OutputGroup.java b/src/main/java/com/sparrowwallet/drongo/wallet/OutputGroup.java index 42f74d9..b66e928 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/OutputGroup.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/OutputGroup.java @@ -1,5 +1,7 @@ package com.sparrowwallet.drongo.wallet; +import com.sparrowwallet.drongo.protocol.ScriptType; + import java.util.ArrayList; import java.util.List; @@ -7,6 +9,7 @@ import static com.sparrowwallet.drongo.protocol.Transaction.WITNESS_SCALE_FACTOR public class OutputGroup { private final List utxos = new ArrayList<>(); + private final ScriptType scriptType; private final int walletBlockHeight; private final long inputWeightUnits; private final double feeRate; @@ -18,7 +21,8 @@ public class OutputGroup { private int depth = Integer.MAX_VALUE; private boolean allInputsFromWallet = true; - public OutputGroup(int walletBlockHeight, long inputWeightUnits, double feeRate, double longTermFeeRate) { + public OutputGroup(ScriptType scriptType, int walletBlockHeight, long inputWeightUnits, double feeRate, double longTermFeeRate) { + this.scriptType = scriptType; this.walletBlockHeight = walletBlockHeight; this.inputWeightUnits = inputWeightUnits; this.feeRate = feeRate; @@ -48,6 +52,10 @@ public class OutputGroup { return utxos; } + public ScriptType getScriptType() { + return scriptType; + } + public long getValue() { return value; } diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/StonewallUtxoSelector.java b/src/main/java/com/sparrowwallet/drongo/wallet/StonewallUtxoSelector.java index 7ef194d..64b2f64 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/StonewallUtxoSelector.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/StonewallUtxoSelector.java @@ -1,15 +1,19 @@ package com.sparrowwallet.drongo.wallet; +import com.sparrowwallet.drongo.protocol.ScriptType; + import java.util.*; import java.util.stream.Collectors; public class StonewallUtxoSelector implements UtxoSelector { + private final ScriptType preferredScriptType; private final long noInputsFee; //Use the same seed so the UTXO selection is deterministic private final Random random = new Random(42); - public StonewallUtxoSelector(long noInputsFee) { + public StonewallUtxoSelector(ScriptType preferredScriptType, long noInputsFee) { + this.preferredScriptType = preferredScriptType; this.noInputsFee = noInputsFee; } @@ -17,6 +21,16 @@ public class StonewallUtxoSelector implements UtxoSelector { public List> selectSets(long targetValue, Collection candidates) { long actualTargetValue = targetValue + noInputsFee; + List preferredCandidates = candidates.stream().filter(outputGroup -> outputGroup.getScriptType().equals(preferredScriptType)).collect(Collectors.toList()); + List> preferredSets = selectSets(targetValue, preferredCandidates, actualTargetValue); + if(!preferredSets.isEmpty()) { + return preferredSets; + } + + return selectSets(targetValue, candidates, actualTargetValue); + } + + private List> selectSets(long targetValue, Collection candidates, long actualTargetValue) { for(int i = 0; i < 10; i++) { List randomized = new ArrayList<>(candidates); Collections.shuffle(randomized, random); diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java index 6e2ea79..584a0d0 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java @@ -117,6 +117,7 @@ public class Wallet extends Persistable implements Comparable { childWallet.purposeNodes.clear(); childWallet.transactions.clear(); childWallet.detachedLabels.clear(); + childWallet.childWallets.clear(); childWallet.storedBlockHeight = null; childWallet.gapLimit = standardAccount.getMinimumGapLimit(); childWallet.birthDate = null; @@ -156,9 +157,11 @@ public class Wallet extends Persistable implements Comparable { public Wallet getChildWallet(StandardAccount account) { for(Wallet childWallet : getChildWallets()) { - for(Keystore keystore : childWallet.getKeystores()) { - if(keystore.getKeyDerivation().getDerivation().get(keystore.getKeyDerivation().getDerivation().size() - 1).equals(account.getChildNumber())) { - return childWallet; + if(!childWallet.isNested()) { + for(Keystore keystore : childWallet.getKeystores()) { + if(keystore.getKeyDerivation().getDerivation().get(keystore.getKeyDerivation().getDerivation().size() - 1).equals(account.getChildNumber())) { + return childWallet; + } } } } @@ -229,7 +232,12 @@ public class Wallet extends Persistable implements Comparable { List allWallets = new ArrayList<>(); Wallet masterWallet = isMasterWallet() ? this : getMasterWallet(); allWallets.add(masterWallet); - allWallets.addAll(masterWallet.getChildWallets()); + for(Wallet childWallet : getChildWallets()) { + if(!childWallet.isNested()) { + allWallets.add(childWallet); + } + } + return allWallets; } @@ -274,7 +282,7 @@ public class Wallet extends Persistable implements Comparable { Address notificationAddress = externalPaymentCode.getNotificationAddress(); for(Map.Entry txoEntry : getWalletTxos().entrySet()) { if(txoEntry.getKey().isSpent()) { - BlockTransaction blockTransaction = transactions.get(txoEntry.getKey().getSpentBy().getHash()); + BlockTransaction blockTransaction = getWalletTransaction(txoEntry.getKey().getSpentBy().getHash()); if(blockTransaction != null) { for(TransactionOutput txOutput : blockTransaction.getTransaction().getOutputs()) { if(notificationAddress.equals(txOutput.getScript().getToAddress())) { @@ -293,6 +301,10 @@ public class Wallet extends Persistable implements Comparable { return Collections.emptyMap(); } + public boolean isNested() { + return isBip47(); + } + public boolean isBip47() { return !isMasterWallet() && getKeystores().size() == 1 && getKeystores().get(0).getSource() == KeystoreSource.SW_PAYMENT_CODE; } @@ -329,7 +341,9 @@ public class Wallet extends Persistable implements Comparable { Set whirlpoolAccounts = new HashSet<>(Set.of(StandardAccount.WHIRLPOOL_PREMIX, StandardAccount.WHIRLPOOL_POSTMIX, StandardAccount.WHIRLPOOL_BADBANK)); for(Wallet childWallet : getChildWallets()) { - whirlpoolAccounts.remove(childWallet.getStandardAccountType()); + if(!childWallet.isNested()) { + whirlpoolAccounts.remove(childWallet.getStandardAccountType()); + } } return whirlpoolAccounts.isEmpty(); @@ -525,7 +539,7 @@ public class Wallet extends Persistable implements Comparable { WalletNode purposeNode; Optional optionalPurposeNode = purposeNodes.stream().filter(node -> node.getKeyPurpose().equals(keyPurpose)).findFirst(); if(optionalPurposeNode.isEmpty()) { - purposeNode = new WalletNode(keyPurpose); + purposeNode = new WalletNode(this, keyPurpose); purposeNodes.add(purposeNode); } else { purposeNode = optionalPurposeNode.get(); @@ -598,10 +612,10 @@ public class Wallet extends Persistable implements Comparable { public Address getAddress(WalletNode node) { if(policyType == PolicyType.SINGLE) { - ECKey pubKey = getPubKey(node); + ECKey pubKey = node.getPubKey(); return scriptType.getAddress(pubKey); } else if(policyType == PolicyType.MULTI) { - List pubKeys = getPubKeys(node); + List pubKeys = node.getPubKeys(); Script script = ScriptType.MULTISIG.getOutputScript(defaultPolicy.getNumSignaturesRequired(), pubKeys); return scriptType.getAddress(script); } else { @@ -611,10 +625,10 @@ public class Wallet extends Persistable implements Comparable { public Script getOutputScript(WalletNode node) { if(policyType == PolicyType.SINGLE) { - ECKey pubKey = getPubKey(node); + ECKey pubKey = node.getPubKey(); return scriptType.getOutputScript(pubKey); } else if(policyType == PolicyType.MULTI) { - List pubKeys = getPubKeys(node); + List pubKeys = node.getPubKeys(); Script script = ScriptType.MULTISIG.getOutputScript(defaultPolicy.getNumSignaturesRequired(), pubKeys); return scriptType.getOutputScript(script); } else { @@ -624,10 +638,10 @@ public class Wallet extends Persistable implements Comparable { public String getOutputDescriptor(WalletNode node) { if(policyType == PolicyType.SINGLE) { - ECKey pubKey = getPubKey(node); + ECKey pubKey = node.getPubKey(); return scriptType.getOutputDescriptor(pubKey); } else if(policyType == PolicyType.MULTI) { - List pubKeys = getPubKeys(node); + List pubKeys = node.getPubKeys(); Script script = ScriptType.MULTISIG.getOutputScript(defaultPolicy.getNumSignaturesRequired(), pubKeys); return scriptType.getOutputDescriptor(script); } else { @@ -662,12 +676,20 @@ public class Wallet extends Persistable implements Comparable { getWalletAddresses(walletAddresses, getNode(keyPurpose)); } + for(Wallet childWallet : getChildWallets()) { + if(childWallet.isNested()) { + for(KeyPurpose keyPurpose : childWallet.getWalletKeyPurposes()) { + getWalletAddresses(walletAddresses, childWallet.getNode(keyPurpose)); + } + } + } + return walletAddresses; } private void getWalletAddresses(Map walletAddresses, WalletNode purposeNode) { for(WalletNode addressNode : purposeNode.getChildren()) { - walletAddresses.put(getAddress(addressNode), addressNode); + walletAddresses.put(addressNode.getAddress(), addressNode); } } @@ -692,12 +714,23 @@ public class Wallet extends Persistable implements Comparable { for(KeyPurpose keyPurpose : keyPurposes) { getWalletOutputScripts(walletOutputScripts, getNode(keyPurpose)); } + + for(Wallet childWallet : getChildWallets()) { + if(childWallet.isNested()) { + for(KeyPurpose keyPurpose : childWallet.getWalletKeyPurposes()) { + if(keyPurposes.contains(keyPurpose)) { + getWalletOutputScripts(walletOutputScripts, childWallet.getNode(keyPurpose)); + } + } + } + } + return walletOutputScripts; } private void getWalletOutputScripts(Map walletOutputScripts, WalletNode purposeNode) { for(WalletNode addressNode : purposeNode.getChildren()) { - walletOutputScripts.put(getOutputScript(addressNode), addressNode); + walletOutputScripts.put(addressNode.getOutputScript(), addressNode); } } @@ -719,6 +752,14 @@ public class Wallet extends Persistable implements Comparable { getWalletTxos(walletTxos, getNode(keyPurpose)); } + for(Wallet childWallet : getChildWallets()) { + if(childWallet.isNested()) { + for(KeyPurpose keyPurpose : childWallet.getWalletKeyPurposes()) { + getWalletTxos(walletTxos, childWallet.getNode(keyPurpose)); + } + } + } + return walletTxos; } @@ -740,6 +781,14 @@ public class Wallet extends Persistable implements Comparable { getWalletUtxos(walletUtxos, getNode(keyPurpose), includeSpentMempoolOutputs); } + for(Wallet childWallet : getChildWallets()) { + if(childWallet.isNested()) { + for(KeyPurpose keyPurpose : childWallet.getWalletKeyPurposes()) { + getWalletUtxos(walletUtxos, childWallet.getNode(keyPurpose), includeSpentMempoolOutputs); + } + } + } + return walletUtxos; } @@ -751,6 +800,51 @@ public class Wallet extends Persistable implements Comparable { } } + public boolean hasTransactions() { + if(!transactions.isEmpty()) { + return true; + } + + for(Wallet childWallet : getChildWallets()) { + if(childWallet.isNested()) { + if(!childWallet.transactions.isEmpty()) { + return true; + } + } + } + + return false; + } + + public BlockTransaction getWalletTransaction(Sha256Hash txid) { + BlockTransaction blockTransaction = transactions.get(txid); + if(blockTransaction != null) { + return blockTransaction; + } + + for(Wallet childWallet : getChildWallets()) { + if(childWallet.isNested()) { + blockTransaction = childWallet.transactions.get(txid); + if(blockTransaction != null) { + return blockTransaction; + } + } + } + + return null; + } + + public Map getWalletTransactions() { + Map allTransactions = new HashMap<>(transactions); + for(Wallet childWallet : getChildWallets()) { + if(childWallet.isNested()) { + allTransactions.putAll(childWallet.transactions); + } + } + + return allTransactions; + } + /** * Determines the dust threshold for creating a new change output in this wallet. * @@ -828,15 +922,15 @@ public class Wallet extends Persistable implements Comparable { WalletNode receiveNode = getFreshNode(KeyPurpose.RECEIVE); Transaction transaction = new Transaction(); - TransactionOutput prevTxOut = transaction.addOutput(1L, getAddress(receiveNode)); + TransactionOutput prevTxOut = transaction.addOutput(1L, receiveNode.getAddress()); TransactionInput txInput = null; if(getPolicyType().equals(PolicyType.SINGLE)) { - ECKey pubKey = getPubKey(receiveNode); + ECKey pubKey = receiveNode.getPubKey(); TransactionSignature signature = TransactionSignature.dummy(getScriptType().getSignatureType()); txInput = getScriptType().addSpendingInput(transaction, prevTxOut, pubKey, signature); } else if(getPolicyType().equals(PolicyType.MULTI)) { - List pubKeys = getPubKeys(receiveNode); + List pubKeys = receiveNode.getPubKeys(); int threshold = getDefaultPolicy().getNumSignaturesRequired(); Map pubKeySignatures = new TreeMap<>(new ECKey.LexicographicECKeyComparator()); for(int i = 0; i < pubKeys.size(); i++) { @@ -856,7 +950,7 @@ public class Wallet extends Persistable implements Comparable { public long getCostOfChange(double feeRate, double longTermFeeRate) { WalletNode changeNode = getFreshNode(KeyPurpose.CHANGE); - TransactionOutput changeOutput = new TransactionOutput(new Transaction(), 1L, getOutputScript(changeNode)); + TransactionOutput changeOutput = new TransactionOutput(new Transaction(), 1L, changeNode.getOutputScript()); return getFee(changeOutput, feeRate, longTermFeeRate); } @@ -898,7 +992,7 @@ public class Wallet extends Persistable implements Comparable { //Add inputs for(Map.Entry selectedUtxo : selectedUtxos.entrySet()) { - Transaction prevTx = getTransactions().get(selectedUtxo.getKey().getHash()).getTransaction(); + Transaction prevTx = getWalletTransaction(selectedUtxo.getKey().getHash()).getTransaction(); TransactionOutput prevTxOut = prevTx.getOutputs().get((int)selectedUtxo.getKey().getIndex()); TransactionInput txInput = addDummySpendingInput(transaction, selectedUtxo.getValue(), prevTxOut); @@ -913,7 +1007,7 @@ public class Wallet extends Persistable implements Comparable { for(int i = 1; i < numSets; i+=2) { WalletNode mixNode = getFreshNode(getChangeKeyPurpose()); txExcludedChangeNodes.add(mixNode); - Payment fakeMixPayment = new Payment(getAddress(mixNode), ".." + mixNode + " (Fake Mix)", totalPaymentAmount, false); + Payment fakeMixPayment = new Payment(mixNode.getAddress(), ".." + mixNode + " (Fake Mix)", totalPaymentAmount, false); fakeMixPayment.setType(Payment.Type.FAKE_MIX); txPayments.add(fakeMixPayment); } @@ -972,7 +1066,7 @@ public class Wallet extends Persistable implements Comparable { while(txExcludedChangeNodes.contains(changeNode)) { changeNode = getFreshNode(getChangeKeyPurpose(), changeNode); } - TransactionOutput changeOutput = new TransactionOutput(transaction, setChangeAmts.iterator().next(), getOutputScript(changeNode)); + TransactionOutput changeOutput = new TransactionOutput(transaction, setChangeAmts.iterator().next(), changeNode.getOutputScript()); double changeVSize = noChangeVSize + changeOutput.getLength() * numSets; long changeFeeRequiredAmt = (fee == null ? (long)Math.floor(feeRate * changeVSize) : fee); changeFeeRequiredAmt = (fee == null && feeRate == Transaction.DEFAULT_MIN_RELAY_FEE ? changeFeeRequiredAmt + 1 : changeFeeRequiredAmt); @@ -984,7 +1078,7 @@ public class Wallet extends Persistable implements Comparable { Map changeMap = new LinkedHashMap<>(); setChangeAmts = getSetChangeAmounts(selectedUtxoSets, totalPaymentAmount, changeFeeRequiredAmt); for(Long setChangeAmt : setChangeAmts) { - transaction.addOutput(setChangeAmt, getOutputScript(changeNode)); + transaction.addOutput(setChangeAmt, changeNode.getOutputScript()); changeMap.put(changeNode, setChangeAmt); changeNode = getFreshNode(getChangeKeyPurpose(), changeNode); } @@ -1041,20 +1135,21 @@ public class Wallet extends Persistable implements Comparable { return changeAmts; } - public TransactionInput addDummySpendingInput(Transaction transaction, WalletNode walletNode, TransactionOutput prevTxOut) { - if(getPolicyType().equals(PolicyType.SINGLE)) { - ECKey pubKey = getPubKey(walletNode); - return getScriptType().addSpendingInput(transaction, prevTxOut, pubKey, TransactionSignature.dummy(getScriptType().getSignatureType())); - } else if(getPolicyType().equals(PolicyType.MULTI)) { - List pubKeys = getPubKeys(walletNode); - int threshold = getDefaultPolicy().getNumSignaturesRequired(); + public static TransactionInput addDummySpendingInput(Transaction transaction, WalletNode walletNode, TransactionOutput prevTxOut) { + Wallet signingWallet = walletNode.getWallet(); + if(signingWallet.getPolicyType().equals(PolicyType.SINGLE)) { + ECKey pubKey = walletNode.getPubKey(); + return signingWallet.getScriptType().addSpendingInput(transaction, prevTxOut, pubKey, TransactionSignature.dummy(signingWallet.getScriptType().getSignatureType())); + } else if(signingWallet.getPolicyType().equals(PolicyType.MULTI)) { + List pubKeys = walletNode.getPubKeys(); + int threshold = signingWallet.getDefaultPolicy().getNumSignaturesRequired(); Map pubKeySignatures = new TreeMap<>(new ECKey.LexicographicECKeyComparator()); for(int i = 0; i < pubKeys.size(); i++) { - pubKeySignatures.put(pubKeys.get(i), i < threshold ? TransactionSignature.dummy(getScriptType().getSignatureType()) : null); + pubKeySignatures.put(pubKeys.get(i), i < threshold ? TransactionSignature.dummy(signingWallet.getScriptType().getSignatureType()) : null); } - return getScriptType().addMultisigSpendingInput(transaction, prevTxOut, threshold, pubKeySignatures); + return signingWallet.getScriptType().addMultisigSpendingInput(transaction, prevTxOut, threshold, pubKeySignatures); } else { - throw new UnsupportedOperationException("Cannot create transaction for policy type " + getPolicyType()); + throw new UnsupportedOperationException("Cannot create transaction for policy type " + signingWallet.getPolicyType()); } } @@ -1104,14 +1199,23 @@ public class Wallet extends Persistable implements Comparable { private List getGroupedUtxos(List utxoFilters, double feeRate, double longTermFeeRate, boolean groupByAddress, boolean includeSpentMempoolOutputs) { List outputGroups = new ArrayList<>(); + Map walletTransactions = getWalletTransactions(); for(KeyPurpose keyPurpose : getWalletKeyPurposes()) { - getGroupedUtxos(outputGroups, getNode(keyPurpose), utxoFilters, feeRate, longTermFeeRate, groupByAddress, includeSpentMempoolOutputs); + getGroupedUtxos(outputGroups, getNode(keyPurpose), utxoFilters, walletTransactions, feeRate, longTermFeeRate, groupByAddress, includeSpentMempoolOutputs); + } + + for(Wallet childWallet : getChildWallets()) { + if(childWallet.isNested()) { + for(KeyPurpose keyPurpose : childWallet.getWalletKeyPurposes()) { + childWallet.getGroupedUtxos(outputGroups, childWallet.getNode(keyPurpose), utxoFilters, walletTransactions, feeRate, longTermFeeRate, groupByAddress, includeSpentMempoolOutputs); + } + } } return outputGroups; } - private void getGroupedUtxos(List outputGroups, WalletNode purposeNode, List utxoFilters, double feeRate, double longTermFeeRate, boolean groupByAddress, boolean includeSpentMempoolOutputs) { + private void getGroupedUtxos(List outputGroups, WalletNode purposeNode, List utxoFilters, Map walletTransactions, double feeRate, double longTermFeeRate, boolean groupByAddress, boolean includeSpentMempoolOutputs) { for(WalletNode addressNode : purposeNode.getChildren()) { OutputGroup outputGroup = null; for(BlockTransactionHashIndex utxo : addressNode.getUnspentTransactionOutputs(includeSpentMempoolOutputs)) { @@ -1121,11 +1225,11 @@ public class Wallet extends Persistable implements Comparable { } if(outputGroup == null || !groupByAddress) { - outputGroup = new OutputGroup(getStoredBlockHeight(), getInputWeightUnits(), feeRate, longTermFeeRate); + outputGroup = new OutputGroup(addressNode.getWallet().getScriptType(), getStoredBlockHeight(), getInputWeightUnits(), feeRate, longTermFeeRate); outputGroups.add(outputGroup); } - outputGroup.add(utxo, allInputsFromWallet(utxo.getHash())); + outputGroup.add(utxo, allInputsFromWallet(walletTransactions, utxo.getHash())); } } } @@ -1137,7 +1241,12 @@ public class Wallet extends Persistable implements Comparable { * @return Whether the transaction was created entirely from inputs that reference outputs that belong to this wallet */ public boolean allInputsFromWallet(Sha256Hash txId) { - BlockTransaction utxoBlkTx = getTransactions().get(txId); + Map allTransactions = getWalletTransactions(); + return allInputsFromWallet(allTransactions, txId); + } + + private boolean allInputsFromWallet(Map walletTransactions, Sha256Hash txId) { + BlockTransaction utxoBlkTx = walletTransactions.get(txId); if(utxoBlkTx == null) { //Provided txId was not a wallet transaction return false; @@ -1145,7 +1254,7 @@ public class Wallet extends Persistable implements Comparable { for(int i = 0; i < utxoBlkTx.getTransaction().getInputs().size(); i++) { TransactionInput utxoTxInput = utxoBlkTx.getTransaction().getInputs().get(i); - BlockTransaction prevBlkTx = getTransactions().get(utxoTxInput.getOutpoint().getHash()); + BlockTransaction prevBlkTx = walletTransactions.get(utxoTxInput.getOutpoint().getHash()); if(prevBlkTx == null) { return false; } @@ -1171,13 +1280,13 @@ public class Wallet extends Persistable implements Comparable { */ public long getMaxSpendable(List
    paymentAddresses, double feeRate) { long maxInputValue = 0; - int inputWeightUnits = getInputWeightUnits(); - long minInputValue = (long)Math.ceil(feeRate * inputWeightUnits / WITNESS_SCALE_FACTOR); Transaction transaction = new Transaction(); for(Map.Entry utxo : getWalletUtxos().entrySet()) { + int inputWeightUnits = utxo.getValue().getWallet().getInputWeightUnits(); + long minInputValue = (long)Math.ceil(feeRate * inputWeightUnits / WITNESS_SCALE_FACTOR); if(utxo.getKey().getValue() > minInputValue) { - Transaction prevTx = getTransactions().get(utxo.getKey().getHash()).getTransaction(); + Transaction prevTx = getWalletTransaction(utxo.getKey().getHash()).getTransaction(); TransactionOutput prevTxOut = prevTx.getOutputs().get((int)utxo.getKey().getIndex()); addDummySpendingInput(transaction, utxo.getValue(), prevTxOut); maxInputValue += utxo.getKey().getValue(); @@ -1207,7 +1316,7 @@ public class Wallet extends Persistable implements Comparable { Map walletOutputScripts = getWalletOutputScripts(); for(TransactionInput txInput : transaction.getInputs()) { - BlockTransaction blockTransaction = transactions.get(txInput.getOutpoint().getHash()); + BlockTransaction blockTransaction = getWalletTransaction(txInput.getOutpoint().getHash()); if(blockTransaction != null && blockTransaction.getTransaction().getOutputs().size() > txInput.getOutpoint().getIndex()) { TransactionOutput utxo = blockTransaction.getTransaction().getOutputs().get((int)txInput.getOutpoint().getIndex()); @@ -1236,20 +1345,22 @@ public class Wallet extends Persistable implements Comparable { for(TransactionInput txInput : signingNodes.keySet()) { WalletNode walletNode = signingNodes.get(txInput); - Map keystoreKeysForNode = getKeystores().stream().collect(Collectors.toMap(keystore -> getScriptType().getOutputKey(keystore.getPubKey(walletNode)), Function.identity(), + Wallet signingWallet = walletNode.getWallet(); + Map keystoreKeysForNode = signingWallet.getKeystores().stream() + .collect(Collectors.toMap(keystore -> signingWallet.getScriptType().getOutputKey(keystore.getPubKey(walletNode)), Function.identity(), (u, v) -> { throw new IllegalStateException("Duplicate keys from different keystores for node " + walletNode); }, LinkedHashMap::new)); Map keySignatureMap = new LinkedHashMap<>(); - BlockTransaction blockTransaction = transactions.get(txInput.getOutpoint().getHash()); + BlockTransaction blockTransaction = signingWallet.transactions.get(txInput.getOutpoint().getHash()); if(blockTransaction != null && blockTransaction.getTransaction().getOutputs().size() > txInput.getOutpoint().getIndex()) { TransactionOutput spentTxo = blockTransaction.getTransaction().getOutputs().get((int)txInput.getOutpoint().getIndex()); Script signingScript = getSigningScript(txInput, spentTxo); Sha256Hash hash; - if(getScriptType() == P2TR) { - List spentOutputs = transaction.getInputs().stream().map(input -> transactions.get(input.getOutpoint().getHash()).getTransaction().getOutputs().get((int)input.getOutpoint().getIndex())).collect(Collectors.toList()); + if(signingWallet.getScriptType() == P2TR) { + List spentOutputs = transaction.getInputs().stream().map(input -> signingWallet.transactions.get(input.getOutpoint().getHash()).getTransaction().getOutputs().get((int)input.getOutpoint().getIndex())).collect(Collectors.toList()); hash = transaction.hashForTaprootSignature(spentOutputs, txInput.getIndex(), !P2TR.isScriptType(signingScript), signingScript, SigHash.ALL_TAPROOT, null); } else if(txInput.hasWitness()) { hash = transaction.hashForWitnessSignature(txInput.getIndex(), signingScript, spentTxo.getValue(), SigHash.ALL); @@ -1336,7 +1447,9 @@ public class Wallet extends Persistable implements Comparable { for(PSBTInput psbtInput : signingNodes.keySet()) { WalletNode walletNode = signingNodes.get(psbtInput); - Map keystoreKeysForNode = getKeystores().stream().collect(Collectors.toMap(keystore -> getScriptType().getOutputKey(keystore.getPubKey(walletNode)), Function.identity(), + Wallet signingWallet = walletNode.getWallet(); + Map keystoreKeysForNode = signingWallet.getKeystores().stream() + .collect(Collectors.toMap(keystore -> signingWallet.getScriptType().getOutputKey(keystore.getPubKey(walletNode)), Function.identity(), (u, v) -> { throw new IllegalStateException("Duplicate keys from different keystores for node " + walletNode); }, LinkedHashMap::new)); @@ -1362,10 +1475,11 @@ public class Wallet extends Persistable implements Comparable { public void sign(PSBT psbt) throws MnemonicException { Map signingNodes = getSigningNodes(psbt); - for(Keystore keystore : getKeystores()) { - if(keystore.hasPrivateKey()) { - for(Map.Entry signingEntry : signingNodes.entrySet()) { - ECKey privKey = getScriptType().getOutputKey(keystore.getKey(signingEntry.getValue())); + for(Map.Entry signingEntry : signingNodes.entrySet()) { + Wallet signingWallet = signingEntry.getValue().getWallet(); + for(Keystore keystore : signingWallet.getKeystores()) { + if(keystore.hasPrivateKey()) { + ECKey privKey = signingWallet.getScriptType().getOutputKey(keystore.getKey(signingEntry.getValue())); PSBTInput psbtInput = signingEntry.getKey(); if(!psbtInput.isSigned()) { @@ -1410,15 +1524,15 @@ public class Wallet extends Persistable implements Comparable { TransactionInput finalizedTxInput; if(getPolicyType().equals(PolicyType.SINGLE)) { - ECKey pubKey = getPubKey(signingNode); + ECKey pubKey = signingNode.getPubKey(); TransactionSignature transactionSignature = psbtInput.isTaproot() ? psbtInput.getTapKeyPathSignature() : psbtInput.getPartialSignature(pubKey); if(transactionSignature == null) { throw new IllegalArgumentException("Pubkey of partial signature does not match wallet pubkey"); } - finalizedTxInput = getScriptType().addSpendingInput(transaction, utxo, pubKey, transactionSignature); + finalizedTxInput = signingNode.getWallet().getScriptType().addSpendingInput(transaction, utxo, pubKey, transactionSignature); } else if(getPolicyType().equals(PolicyType.MULTI)) { - List pubKeys = getPubKeys(signingNode); + List pubKeys = signingNode.getPubKeys(); Map pubKeySignatures = new TreeMap<>(new ECKey.LexicographicECKeyComparator()); for(ECKey pubKey : pubKeys) { @@ -1430,7 +1544,7 @@ public class Wallet extends Persistable implements Comparable { throw new IllegalArgumentException("Pubkeys of partial signatures do not match wallet pubkeys"); } - finalizedTxInput = getScriptType().addMultisigSpendingInput(transaction, utxo, threshold, pubKeySignatures); + finalizedTxInput = signingNode.getWallet().getScriptType().addMultisigSpendingInput(transaction, utxo, threshold, pubKeySignatures); } else { throw new UnsupportedOperationException("Cannot finalise PSBT for policy type " + getPolicyType()); } @@ -1471,6 +1585,12 @@ public class Wallet extends Persistable implements Comparable { transactions.clear(); storedBlockHeight = 0; + + for(Wallet childWallet : getChildWallets()) { + if(childWallet.isNested()) { + childWallet.clearHistory(); + } + } } private Map getDetachedLabels(boolean includeAddresses) { @@ -1484,7 +1604,7 @@ public class Wallet extends Persistable implements Comparable { for(WalletNode purposeNode : purposeNodes) { for(WalletNode addressNode : purposeNode.getChildren()) { if(includeAddresses && addressNode.getLabel() != null && !addressNode.getLabel().isEmpty()) { - labels.put(getAddress(addressNode).toString(), addressNode.getLabel()); + labels.put(addressNode.getAddress().toString(), addressNode.getLabel()); } for(BlockTransactionHashIndex output : addressNode.getTransactionOutputs()) { @@ -1637,7 +1757,7 @@ public class Wallet extends Persistable implements Comparable { copy.getKeystores().add(keystore.copy()); } for(WalletNode node : purposeNodes) { - copy.purposeNodes.add(node.copy()); + copy.purposeNodes.add(node.copy(copy)); } for(Sha256Hash hash : transactions.keySet()) { copy.transactions.put(hash, transactions.get(hash)); @@ -1684,6 +1804,12 @@ public class Wallet extends Persistable implements Comparable { } } + for(Wallet childWallet : getChildWallets()) { + if(childWallet.isNested() && childWallet.isEncrypted()) { + return true; + } + } + return false; } @@ -1691,24 +1817,48 @@ public class Wallet extends Persistable implements Comparable { for(Keystore keystore : keystores) { keystore.encrypt(key); } + + for(Wallet childWallet : getChildWallets()) { + if(childWallet.isNested()) { + childWallet.encrypt(key); + } + } } public void decrypt(CharSequence password) { for(Keystore keystore : keystores) { keystore.decrypt(password); } + + for(Wallet childWallet : getChildWallets()) { + if(childWallet.isNested()) { + childWallet.decrypt(password); + } + } } public void decrypt(Key key) { for(Keystore keystore : keystores) { keystore.decrypt(key); } + + for(Wallet childWallet : getChildWallets()) { + if(childWallet.isNested()) { + childWallet.decrypt(key); + } + } } public void clearPrivate() { for(Keystore keystore : keystores) { keystore.clearPrivate(); } + + for(Wallet childWallet : getChildWallets()) { + if(childWallet.isNested()) { + childWallet.clearPrivate(); + } + } } @Override diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/WalletNode.java b/src/main/java/com/sparrowwallet/drongo/wallet/WalletNode.java index 2394116..ae1374a 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/WalletNode.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/WalletNode.java @@ -2,7 +2,10 @@ package com.sparrowwallet.drongo.wallet; import com.sparrowwallet.drongo.KeyDerivation; import com.sparrowwallet.drongo.KeyPurpose; +import com.sparrowwallet.drongo.address.Address; import com.sparrowwallet.drongo.crypto.ChildNumber; +import com.sparrowwallet.drongo.crypto.ECKey; +import com.sparrowwallet.drongo.protocol.Script; import java.util.*; import java.util.stream.Collectors; @@ -13,29 +16,53 @@ public class WalletNode extends Persistable implements Comparable { private TreeSet children = new TreeSet<>(); private TreeSet transactionOutputs = new TreeSet<>(); + private transient Wallet wallet; private transient KeyPurpose keyPurpose; private transient int index = -1; private transient List derivation; + //Cache pubkeys for BIP47 wallets to avoid time-consuming ECDH calculations + private transient ECKey cachedPubKey; + + //Note use of this constructor must be followed by setting the wallet field public WalletNode(String derivationPath) { this.derivationPath = derivationPath; parseDerivation(); } - public WalletNode(KeyPurpose keyPurpose) { + public WalletNode(Wallet wallet, String derivationPath) { + this.wallet = wallet; + this.derivationPath = derivationPath; + parseDerivation(); + } + + public WalletNode(Wallet wallet, KeyPurpose keyPurpose) { + this.wallet = wallet; this.derivation = List.of(keyPurpose.getPathIndex()); this.derivationPath = KeyDerivation.writePath(derivation); this.keyPurpose = keyPurpose; this.index = keyPurpose.getPathIndex().num(); } - public WalletNode(KeyPurpose keyPurpose, int index) { + public WalletNode(Wallet wallet, KeyPurpose keyPurpose, int index) { + this.wallet = wallet; this.derivation = List.of(keyPurpose.getPathIndex(), new ChildNumber(index)); this.derivationPath = KeyDerivation.writePath(derivation); this.keyPurpose = keyPurpose; this.index = index; } + public Wallet getWallet() { + return wallet; + } + + public void setWallet(Wallet wallet) { + this.wallet = wallet; + for(WalletNode childNode : getChildren()) { + childNode.setWallet(wallet); + } + } + public String getDerivationPath() { return derivationPath; } @@ -154,7 +181,7 @@ public class WalletNode extends Persistable implements Comparable { Set newNodes = fillToIndex(index); if(!wallet.getDetachedLabels().isEmpty() && wallet.isValid()) { for(WalletNode newNode : newNodes) { - String label = wallet.getDetachedLabels().remove(wallet.getAddress(newNode).toString()); + String label = wallet.getDetachedLabels().remove(newNode.getAddress().toString()); if(label != null && (newNode.getLabel() == null || newNode.getLabel().isEmpty())) { newNode.setLabel(label); } @@ -167,7 +194,7 @@ public class WalletNode extends Persistable implements Comparable { public synchronized Set fillToIndex(int index) { Set newNodes = new TreeSet<>(); for(int i = 0; i <= index; i++) { - WalletNode node = new WalletNode(getKeyPurpose(), i); + WalletNode node = new WalletNode(wallet, getKeyPurpose(), i); if(children.add(node)) { newNodes.add(node); } @@ -190,6 +217,35 @@ public class WalletNode extends Persistable implements Comparable { return highestNode == null ? null : highestNode.index; } + public ECKey getPubKey() { + if(cachedPubKey != null) { + return cachedPubKey; + } + + if(wallet.isBip47()) { + cachedPubKey = wallet.getPubKey(this); + return cachedPubKey; + } + + return wallet.getPubKey(this); + } + + public List getPubKeys() { + return wallet.getPubKeys(this); + } + + public Address getAddress() { + return wallet.getAddress(this); + } + + public Script getOutputScript() { + return wallet.getOutputScript(this); + } + + public String getOutputDescriptor() { + return wallet.getOutputDescriptor(this); + } + @Override public String toString() { return derivationPath.replace("m", ".."); @@ -200,12 +256,12 @@ public class WalletNode extends Persistable implements Comparable { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; WalletNode node = (WalletNode) o; - return derivationPath.equals(node.derivationPath); + return Objects.equals(wallet, node.wallet) && derivationPath.equals(node.derivationPath); } @Override public int hashCode() { - return derivationPath.hashCode(); + return Objects.hash(wallet, derivationPath); } @Override @@ -232,13 +288,13 @@ public class WalletNode extends Persistable implements Comparable { } } - public WalletNode copy() { - WalletNode copy = new WalletNode(derivationPath); + public WalletNode copy(Wallet walletCopy) { + WalletNode copy = new WalletNode(walletCopy, derivationPath); copy.setId(getId()); copy.setLabel(label); for(WalletNode child : getChildren()) { - copy.children.add(child.copy()); + copy.children.add(child.copy(walletCopy)); } for(BlockTransactionHashIndex txo : getTransactionOutputs()) { diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/WalletTransaction.java b/src/main/java/com/sparrowwallet/drongo/wallet/WalletTransaction.java index 36b0282..8248fdf 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/WalletTransaction.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/WalletTransaction.java @@ -79,7 +79,7 @@ public class WalletTransaction { } public Address getChangeAddress(WalletNode changeNode) { - return getWallet().getAddress(changeNode); + return changeNode.getAddress(); } public long getFee() { diff --git a/src/test/java/com/sparrowwallet/drongo/bip47/PaymentCodeTest.java b/src/test/java/com/sparrowwallet/drongo/bip47/PaymentCodeTest.java index e4cd501..31c05a9 100644 --- a/src/test/java/com/sparrowwallet/drongo/bip47/PaymentCodeTest.java +++ b/src/test/java/com/sparrowwallet/drongo/bip47/PaymentCodeTest.java @@ -126,15 +126,15 @@ public class PaymentCodeTest { Assert.assertEquals("1JDdmqFLhpzcUwPeinhJbUPw4Co3aWLyzW", paymentCodeAlice.getNotificationAddress().toString()); WalletNode sendNode0 = aliceBip47Wallet.getFreshNode(KeyPurpose.SEND); - Address address0 = aliceBip47Wallet.getAddress(sendNode0); + Address address0 = sendNode0.getAddress(); Assert.assertEquals("141fi7TY3h936vRUKh1qfUZr8rSBuYbVBK", address0.toString()); WalletNode sendNode1 = aliceBip47Wallet.getFreshNode(KeyPurpose.SEND, sendNode0); - Address address1 = aliceBip47Wallet.getAddress(sendNode1); + Address address1 = sendNode1.getAddress(); Assert.assertEquals("12u3Uued2fuko2nY4SoSFGCoGLCBUGPkk6", address1.toString()); WalletNode sendNode2 = aliceBip47Wallet.getFreshNode(KeyPurpose.SEND, sendNode1); - Address address2 = aliceBip47Wallet.getAddress(sendNode2); + Address address2 = sendNode2.getAddress(); Assert.assertEquals("1FsBVhT5dQutGwaPePTYMe5qvYqqjxyftc", address2.toString()); DeterministicSeed bobSeed = new DeterministicSeed("reward upper indicate eight swift arch injury crystal super wrestle already dentist", "", 0, DeterministicSeed.Type.BIP39); @@ -149,15 +149,15 @@ public class PaymentCodeTest { Assert.assertEquals("1ChvUUvht2hUQufHBXF8NgLhW8SwE2ecGV", paymentCodeBob.getNotificationAddress().toString()); WalletNode receiveNode0 = bobBip47Wallet.getFreshNode(KeyPurpose.RECEIVE); - Address receiveAddress0 = bobBip47Wallet.getAddress(receiveNode0); + Address receiveAddress0 = receiveNode0.getAddress(); Assert.assertEquals("141fi7TY3h936vRUKh1qfUZr8rSBuYbVBK", receiveAddress0.toString()); WalletNode receiveNode1 = bobBip47Wallet.getFreshNode(KeyPurpose.RECEIVE, receiveNode0); - Address receiveAddress1 = bobBip47Wallet.getAddress(receiveNode1); + Address receiveAddress1 = receiveNode1.getAddress(); Assert.assertEquals("12u3Uued2fuko2nY4SoSFGCoGLCBUGPkk6", receiveAddress1.toString()); WalletNode receiveNode2 = bobBip47Wallet.getFreshNode(KeyPurpose.RECEIVE, receiveNode1); - Address receiveAddress2 = bobBip47Wallet.getAddress(receiveNode2); + Address receiveAddress2 = receiveNode2.getAddress(); Assert.assertEquals("1FsBVhT5dQutGwaPePTYMe5qvYqqjxyftc", receiveAddress2.toString()); ECKey privKey0 = bobWallet.getKeystores().get(0).getKey(receiveNode0); diff --git a/src/test/java/com/sparrowwallet/drongo/crypto/ECKeyTest.java b/src/test/java/com/sparrowwallet/drongo/crypto/ECKeyTest.java index 8fb8808..3897aca 100644 --- a/src/test/java/com/sparrowwallet/drongo/crypto/ECKeyTest.java +++ b/src/test/java/com/sparrowwallet/drongo/crypto/ECKeyTest.java @@ -22,7 +22,7 @@ public class ECKeyTest { wallet.setDefaultPolicy(Policy.getPolicy(PolicyType.SINGLE, ScriptType.P2PKH, wallet.getKeystores(), 1)); WalletNode firstReceive = wallet.getNode(KeyPurpose.RECEIVE).getChildren().iterator().next(); - Address address = wallet.getAddress(firstReceive); + Address address = firstReceive.getAddress(); Assert.assertEquals("14JmU9a7SzieZNEtBnsZo688rt3mGrw6hr", address.toString()); ECKey privKey = keystore.getKey(firstReceive); diff --git a/src/test/java/com/sparrowwallet/drongo/wallet/WalletTest.java b/src/test/java/com/sparrowwallet/drongo/wallet/WalletTest.java index d9f23e1..2dc3155 100644 --- a/src/test/java/com/sparrowwallet/drongo/wallet/WalletTest.java +++ b/src/test/java/com/sparrowwallet/drongo/wallet/WalletTest.java @@ -104,8 +104,10 @@ public class WalletTest { wallet.getKeystores().add(keystore); wallet.setDefaultPolicy(Policy.getPolicy(PolicyType.SINGLE, ScriptType.P2PKH, wallet.getKeystores(), 1)); - Assert.assertEquals("12kTQjuWDp7Uu6PwY6CsS1KLTt3d1DBHZa", wallet.getAddress(new WalletNode(KeyPurpose.RECEIVE, 0)).toString()); - Assert.assertEquals("1HbQwQCitHQxVtP39isXmUdHx7hQCZovrK", wallet.getAddress(new WalletNode(KeyPurpose.RECEIVE, 1)).toString()); + WalletNode receive0 = new WalletNode(wallet, KeyPurpose.RECEIVE, 0); + Assert.assertEquals("12kTQjuWDp7Uu6PwY6CsS1KLTt3d1DBHZa", receive0.getAddress().toString()); + WalletNode receive1 = new WalletNode(wallet, KeyPurpose.RECEIVE, 1); + Assert.assertEquals("1HbQwQCitHQxVtP39isXmUdHx7hQCZovrK", receive1.getAddress().toString()); } @Test @@ -119,8 +121,10 @@ public class WalletTest { wallet.getKeystores().add(keystore); wallet.setDefaultPolicy(Policy.getPolicy(PolicyType.SINGLE, ScriptType.P2SH_P2WPKH, wallet.getKeystores(), 1)); - Assert.assertEquals("3NZLE4TntsjtcZ5MbrfxwtYo9meBVybVQj", wallet.getAddress(new WalletNode(KeyPurpose.RECEIVE, 0)).toString()); - Assert.assertEquals("32YBBuRsp8XTeLx4T6BmD2L4nANGaNDkSg", wallet.getAddress(new WalletNode(KeyPurpose.RECEIVE, 1)).toString()); + WalletNode receive0 = new WalletNode(wallet, KeyPurpose.RECEIVE, 0); + Assert.assertEquals("3NZLE4TntsjtcZ5MbrfxwtYo9meBVybVQj", receive0.getAddress().toString()); + WalletNode receive1 = new WalletNode(wallet, KeyPurpose.RECEIVE, 1); + Assert.assertEquals("32YBBuRsp8XTeLx4T6BmD2L4nANGaNDkSg", receive1.getAddress().toString()); } @Test @@ -134,8 +138,10 @@ public class WalletTest { wallet.getKeystores().add(keystore); wallet.setDefaultPolicy(Policy.getPolicy(PolicyType.SINGLE, ScriptType.P2WPKH, wallet.getKeystores(), 1)); - Assert.assertEquals("bc1quvxdut936uswuxwxrk6nvjmgwxh463r0fjwn55", wallet.getAddress(new WalletNode(KeyPurpose.RECEIVE, 0)).toString()); - Assert.assertEquals("bc1q95j2862dz7mqpraw6qdjc70gumyu5z7adgq9x9", wallet.getAddress(new WalletNode(KeyPurpose.RECEIVE, 1)).toString()); + WalletNode receive0 = new WalletNode(wallet, KeyPurpose.RECEIVE, 0); + Assert.assertEquals("bc1quvxdut936uswuxwxrk6nvjmgwxh463r0fjwn55", receive0.getAddress().toString()); + WalletNode receive1 = new WalletNode(wallet, KeyPurpose.RECEIVE, 1); + Assert.assertEquals("bc1q95j2862dz7mqpraw6qdjc70gumyu5z7adgq9x9", receive1.getAddress().toString()); } @Test @@ -159,8 +165,10 @@ public class WalletTest { wallet.getKeystores().add(keystore2); wallet.setDefaultPolicy(Policy.getPolicy(PolicyType.MULTI, ScriptType.P2SH, wallet.getKeystores(), 2)); - Assert.assertEquals("38kq6yz4VcYymTExQPY3gppbz38mtPLveK", wallet.getAddress(new WalletNode(KeyPurpose.RECEIVE, 0)).toString()); - Assert.assertEquals("3EdKaNsnjBTBggWcSMRyVju6GbHWy68mAH", wallet.getAddress(new WalletNode(KeyPurpose.CHANGE, 1)).toString()); + WalletNode receive0 = new WalletNode(wallet, KeyPurpose.RECEIVE, 0); + Assert.assertEquals("38kq6yz4VcYymTExQPY3gppbz38mtPLveK", receive0.getAddress().toString()); + WalletNode receive1 = new WalletNode(wallet, KeyPurpose.CHANGE, 1); + Assert.assertEquals("3EdKaNsnjBTBggWcSMRyVju6GbHWy68mAH", receive1.getAddress().toString()); } @Test @@ -184,8 +192,10 @@ public class WalletTest { wallet.getKeystores().add(keystore2); wallet.setDefaultPolicy(Policy.getPolicy(PolicyType.MULTI, ScriptType.P2SH_P2WSH, wallet.getKeystores(), 2)); - Assert.assertEquals("3Mw8xqAHh8g3eBvh7q1UEUmoexqdXDK9Tf", wallet.getAddress(new WalletNode(KeyPurpose.RECEIVE, 0)).toString()); - Assert.assertEquals("35dFo1ivJ8jyHpyf42MWvnYf5LBU8Siren", wallet.getAddress(new WalletNode(KeyPurpose.CHANGE, 1)).toString()); + WalletNode receive0 = new WalletNode(wallet, KeyPurpose.RECEIVE, 0); + Assert.assertEquals("3Mw8xqAHh8g3eBvh7q1UEUmoexqdXDK9Tf", receive0.getAddress().toString()); + WalletNode receive1 = new WalletNode(wallet, KeyPurpose.CHANGE, 1); + Assert.assertEquals("35dFo1ivJ8jyHpyf42MWvnYf5LBU8Siren", receive1.getAddress().toString()); } @Test @@ -209,8 +219,10 @@ public class WalletTest { wallet.getKeystores().add(keystore2); wallet.setDefaultPolicy(Policy.getPolicy(PolicyType.MULTI, ScriptType.P2WSH, wallet.getKeystores(), 2)); - Assert.assertEquals("bc1q20e4vm656h5lvmngz9ztz6hjzftvh39yzngqhuqzk8qzj7tqnzaqgclrwc", wallet.getAddress(new WalletNode(KeyPurpose.RECEIVE, 0)).toString()); - Assert.assertEquals("bc1q2epdx7dplwaas2jucfrzmxm8350rqh68hs6vqreysku80ye44mfqla85f2", wallet.getAddress(new WalletNode(KeyPurpose.CHANGE, 1)).toString()); + WalletNode receive0 = new WalletNode(wallet, KeyPurpose.RECEIVE, 0); + Assert.assertEquals("bc1q20e4vm656h5lvmngz9ztz6hjzftvh39yzngqhuqzk8qzj7tqnzaqgclrwc", receive0.getAddress().toString()); + WalletNode receive1 = new WalletNode(wallet, KeyPurpose.CHANGE, 1); + Assert.assertEquals("bc1q2epdx7dplwaas2jucfrzmxm8350rqh68hs6vqreysku80ye44mfqla85f2", receive1.getAddress().toString()); } @Test @@ -227,6 +239,7 @@ public class WalletTest { List derivation = List.of(keystore.getExtendedPublicKey().getKeyChildNumber(), new ChildNumber(0)); Assert.assertEquals("027ecc656f4b91b92881b6f07cf876cd2e42b20df7acc4df54fc3315fbb2d13e1c", Utils.bytesToHex(extendedKey.getKey(derivation).getPubKey())); - Assert.assertEquals("bc1qarzeu6ncapyvjzdeayjq8vnzp6uvcn4eaeuuqq", wallet.getAddress(new WalletNode(KeyPurpose.RECEIVE, 0)).toString()); + WalletNode receive0 = new WalletNode(wallet, KeyPurpose.RECEIVE, 0); + Assert.assertEquals("bc1qarzeu6ncapyvjzdeayjq8vnzp6uvcn4eaeuuqq", receive0.getAddress().toString()); } } From 04631be8c10bf0ef72ebd7f7ef26254cccecb282 Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Fri, 4 Mar 2022 10:35:20 +0200 Subject: [PATCH 107/155] copy label on wallet copy --- src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java index 584a0d0..c37a5a8 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java @@ -114,6 +114,7 @@ public class Wallet extends Persistable implements Comparable { childWallet.setId(null); childWallet.setName(standardAccount.getName()); + childWallet.setLabel(null); childWallet.purposeNodes.clear(); childWallet.transactions.clear(); childWallet.detachedLabels.clear(); @@ -1744,6 +1745,7 @@ public class Wallet extends Persistable implements Comparable { public Wallet copy() { Wallet copy = new Wallet(name); copy.setId(getId()); + copy.setLabel(label); copy.setMasterWallet(masterWallet); for(Wallet childWallet : childWallets) { Wallet copyChildWallet = childWallet.copy(); From 640176153016e6b38b367d6d7e37ecf15cfee745 Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Thu, 17 Mar 2022 09:44:47 +0200 Subject: [PATCH 108/155] automatically label new bip47 receive addresses to identify incoming bip47 payments --- .../drongo/wallet/WalletNode.java | 21 ++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/WalletNode.java b/src/main/java/com/sparrowwallet/drongo/wallet/WalletNode.java index ae1374a..af1fe5d 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/WalletNode.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/WalletNode.java @@ -179,11 +179,22 @@ public class WalletNode extends Persistable implements Comparable { public Set fillToIndex(Wallet wallet, int index) { Set newNodes = fillToIndex(index); - if(!wallet.getDetachedLabels().isEmpty() && wallet.isValid()) { - for(WalletNode newNode : newNodes) { - String label = wallet.getDetachedLabels().remove(newNode.getAddress().toString()); - if(label != null && (newNode.getLabel() == null || newNode.getLabel().isEmpty())) { - newNode.setLabel(label); + if(wallet.isValid()) { + if(!wallet.getDetachedLabels().isEmpty()) { + for(WalletNode newNode : newNodes) { + String label = wallet.getDetachedLabels().remove(newNode.getAddress().toString()); + if(label != null && (newNode.getLabel() == null || newNode.getLabel().isEmpty())) { + newNode.setLabel(label); + } + } + } + + if(wallet.isBip47() && keyPurpose == KeyPurpose.RECEIVE && wallet.getLabel() != null && !newNodes.isEmpty()) { + String suffix = " " + wallet.getScriptType().getName(); + for(WalletNode newNode : newNodes) { + if((newNode.getLabel() == null || newNode.getLabel().isEmpty()) && wallet.getLabel().endsWith(suffix)) { + newNode.setLabel("From " + wallet.getLabel().substring(0, wallet.getLabel().length() - suffix.length())); + } } } } From fe57ad3e7a16fac968910f6581075fdbd79e10a8 Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Thu, 17 Mar 2022 10:33:32 +0200 Subject: [PATCH 109/155] set bip47 wallet label before creating addresses --- src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java index c37a5a8..af362b5 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java @@ -170,8 +170,8 @@ public class Wallet extends Persistable implements Comparable { return null; } - public Wallet addChildWallet(PaymentCode externalPaymentCode, ScriptType childScriptType, BlockTransactionHashIndex notificationOutput, BlockTransaction notificationTransaction) { - Wallet bip47Wallet = addChildWallet(externalPaymentCode, childScriptType); + public Wallet addChildWallet(PaymentCode externalPaymentCode, ScriptType childScriptType, BlockTransactionHashIndex notificationOutput, BlockTransaction notificationTransaction, String label) { + Wallet bip47Wallet = addChildWallet(externalPaymentCode, childScriptType, label); WalletNode notificationNode = bip47Wallet.getNode(KeyPurpose.NOTIFICATION); notificationNode.getTransactionOutputs().add(notificationOutput); bip47Wallet.updateTransactions(Map.of(notificationTransaction.getHash(), notificationTransaction)); @@ -179,7 +179,7 @@ public class Wallet extends Persistable implements Comparable { return bip47Wallet; } - public Wallet addChildWallet(PaymentCode externalPaymentCode, ScriptType childScriptType) { + public Wallet addChildWallet(PaymentCode externalPaymentCode, ScriptType childScriptType, String label) { if(policyType != PolicyType.SINGLE) { throw new IllegalStateException("Cannot add payment code wallet to " + policyType.getName() + " wallet"); } @@ -194,6 +194,7 @@ public class Wallet extends Persistable implements Comparable { } Wallet childWallet = new Wallet(childScriptType + "-" + externalPaymentCode.toString()); + childWallet.setLabel(label); childWallet.setPolicyType(PolicyType.SINGLE); childWallet.setScriptType(childScriptType); childWallet.setGapLimit(5); From 88bd6ada98d98451c580ee4209ec86ec95fa2c94 Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Mon, 21 Mar 2022 09:39:04 +0200 Subject: [PATCH 110/155] disable bip47 support for taproot script type --- src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java index af362b5..93f6b10 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java @@ -184,7 +184,7 @@ public class Wallet extends Persistable implements Comparable { throw new IllegalStateException("Cannot add payment code wallet to " + policyType.getName() + " wallet"); } - if(scriptType != P2PKH && scriptType != P2WPKH) { + if(scriptType != P2PKH && scriptType != P2SH_P2WPKH && scriptType != P2WPKH) { throw new IllegalStateException("Cannot add payment code wallet to " + scriptType.getName() + " wallet"); } @@ -244,7 +244,8 @@ public class Wallet extends Persistable implements Comparable { } public boolean hasPaymentCode() { - return getKeystores().size() == 1 && getKeystores().get(0).getBip47ExtendedPrivateKey() != null; + return getKeystores().size() == 1 && getKeystores().get(0).getBip47ExtendedPrivateKey() != null && policyType == PolicyType.SINGLE + && (scriptType == P2PKH || scriptType == P2SH_P2WPKH || scriptType == P2WPKH); } public PaymentCode getPaymentCode() { From 74e32bab3d4f229e1b0207c7980c99e04c5115fa Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Tue, 22 Mar 2022 09:14:29 +0200 Subject: [PATCH 111/155] simplify automatic master wallet label --- src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java index 93f6b10..19ce824 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java @@ -90,7 +90,7 @@ public class Wallet extends Persistable implements Comparable { public String getAutomaticName() { int account = getAccountIndex(); - return (account < 0 || account > 9) ? getName() : (!isWhirlpoolMasterWallet() || account > 1 ? "Account #" + account : "Deposit"); + return (account < 1 || account > 9) ? "Deposit" : "Account #" + account; } public String getMasterName() { From d1088fe9ee6da0e53fcfdff020cab3c16c15702b Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Tue, 29 Mar 2022 11:49:49 +0200 Subject: [PATCH 112/155] support psbt taproot bip32 derivation field, fix taproot signature verification --- .../com/sparrowwallet/drongo/psbt/PSBT.java | 7 +-- .../sparrowwallet/drongo/psbt/PSBTEntry.java | 45 ++++++++++++++++++- .../sparrowwallet/drongo/psbt/PSBTInput.java | 43 +++++++++++++++++- .../drongo/bip47/PaymentCodeTest.java | 4 +- 4 files changed, 91 insertions(+), 8 deletions(-) diff --git a/src/main/java/com/sparrowwallet/drongo/psbt/PSBT.java b/src/main/java/com/sparrowwallet/drongo/psbt/PSBT.java index cf97b56..77ecef7 100644 --- a/src/main/java/com/sparrowwallet/drongo/psbt/PSBT.java +++ b/src/main/java/com/sparrowwallet/drongo/psbt/PSBT.java @@ -330,15 +330,16 @@ public class PSBT { int inputIndex = this.psbtInputs.size(); PSBTInput input = new PSBTInput(this, inputEntries, transaction, inputIndex); + this.psbtInputs.add(input); + } - if(verifySignatures) { + if(verifySignatures) { + for(PSBTInput input : psbtInputs) { boolean verified = input.verifySignatures(); if(!verified && input.getPartialSignatures().size() > 0) { throw new PSBTSignatureException("Unverifiable partial signatures provided"); } } - - this.psbtInputs.add(input); } } diff --git a/src/main/java/com/sparrowwallet/drongo/psbt/PSBTEntry.java b/src/main/java/com/sparrowwallet/drongo/psbt/PSBTEntry.java index cf7575b..fa4326d 100644 --- a/src/main/java/com/sparrowwallet/drongo/psbt/PSBTEntry.java +++ b/src/main/java/com/sparrowwallet/drongo/psbt/PSBTEntry.java @@ -3,6 +3,8 @@ package com.sparrowwallet.drongo.psbt; import com.sparrowwallet.drongo.KeyDerivation; import com.sparrowwallet.drongo.Utils; import com.sparrowwallet.drongo.crypto.ChildNumber; +import com.sparrowwallet.drongo.protocol.Sha256Hash; +import com.sparrowwallet.drongo.protocol.VarInt; import java.io.ByteArrayOutputStream; import java.nio.ByteBuffer; @@ -10,6 +12,7 @@ import java.nio.ByteOrder; import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import java.util.Map; public class PSBTEntry { private final byte[] key; @@ -55,6 +58,25 @@ public class PSBTEntry { } } + public static Map> parseTaprootKeyDerivation(byte[] data) throws PSBTParseException { + if(data.length < 1) { + throw new PSBTParseException("Invalid taproot key derivation: no bytes"); + } + VarInt varInt = new VarInt(data, 0); + int offset = varInt.getOriginalSizeInBytes(); + + if(data.length < offset + (varInt.value * 32)) { + throw new PSBTParseException("Invalid taproot key derivation: not enough bytes for leaf hashes"); + } + List leafHashes = new ArrayList<>(); + for(int i = 0; i < varInt.value; i++) { + leafHashes.add(Sha256Hash.wrap(Arrays.copyOfRange(data, offset + (i * 32), offset + (i * 32) + 32))); + } + + KeyDerivation keyDerivation = parseKeyDerivation(Arrays.copyOfRange(data, offset + (leafHashes.size() * 32), data.length)); + return Map.of(keyDerivation, leafHashes); + } + public static KeyDerivation parseKeyDerivation(byte[] data) throws PSBTParseException { if(data.length < 4) { throw new PSBTParseException("Invalid master fingerprint specified: not enough bytes"); @@ -91,6 +113,19 @@ public class PSBTEntry { return path; } + public static byte[] serializeTaprootKeyDerivation(List leafHashes, KeyDerivation keyDerivation) { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + + VarInt hashesLen = new VarInt(leafHashes.size()); + baos.writeBytes(hashesLen.encode()); + for(Sha256Hash leafHash : leafHashes) { + baos.writeBytes(leafHash.getBytes()); + } + + baos.writeBytes(serializeKeyDerivation(keyDerivation)); + return baos.toByteArray(); + } + public static byte[] serializeKeyDerivation(KeyDerivation keyDerivation) { ByteArrayOutputStream baos = new ByteArrayOutputStream(); byte[] fingerprintBytes = Utils.hexToBytes(keyDerivation.getMasterFingerprint()); @@ -210,13 +245,19 @@ public class PSBTEntry { public void checkOneBytePlusXpubKey() throws PSBTParseException { if(this.getKey().length != 79) { - throw new PSBTParseException("PSBT key type must be one byte"); + throw new PSBTParseException("PSBT key type must be one byte plus xpub"); } } public void checkOneBytePlusPubKey() throws PSBTParseException { if(this.getKey().length != 34) { - throw new PSBTParseException("PSBT key type must be one byte"); + throw new PSBTParseException("PSBT key type must be one byte plus pub key"); + } + } + + public void checkOneBytePlusXOnlyPubKey() throws PSBTParseException { + if(this.getKey().length != 33) { + throw new PSBTParseException("PSBT key type must be one byte plus x only pub key"); } } } diff --git a/src/main/java/com/sparrowwallet/drongo/psbt/PSBTInput.java b/src/main/java/com/sparrowwallet/drongo/psbt/PSBTInput.java index 7b67a63..71bab98 100644 --- a/src/main/java/com/sparrowwallet/drongo/psbt/PSBTInput.java +++ b/src/main/java/com/sparrowwallet/drongo/psbt/PSBTInput.java @@ -29,6 +29,7 @@ public class PSBTInput { public static final byte PSBT_IN_POR_COMMITMENT = 0x09; public static final byte PSBT_IN_PROPRIETARY = (byte)0xfc; public static final byte PSBT_IN_TAP_KEY_SIG = 0x13; + public static final byte PSBT_IN_TAP_BIP32_DERIVATION = 0x16; public static final byte PSBT_IN_TAP_INTERNAL_KEY = 0x17; private final PSBT psbt; @@ -44,6 +45,7 @@ public class PSBTInput { private String porCommitment; private final Map proprietary = new LinkedHashMap<>(); private TransactionSignature tapKeyPathSignature; + private Map>> tapDerivedPublicKeys = new LinkedHashMap<>(); private ECKey tapInternalKey; private final Transaction transaction; @@ -79,6 +81,11 @@ public class PSBTInput { this.tapInternalKey = tapInternalKey; + if(tapInternalKey != null && !derivedPublicKeys.values().isEmpty()) { + KeyDerivation tapKeyDerivation = derivedPublicKeys.values().iterator().next(); + tapDerivedPublicKeys.put(tapInternalKey, Map.of(tapKeyDerivation, Collections.emptyList())); + } + this.sigHash = getDefaultSigHash(); } @@ -121,6 +128,10 @@ public class PSBTInput { case PSBT_IN_PARTIAL_SIG: entry.checkOneBytePlusPubKey(); ECKey sigPublicKey = ECKey.fromPublicOnly(entry.getKeyData()); + if(entry.getData().length == 64 || entry.getData().length == 65) { + log.error("Schnorr signature provided as ECDSA partial signature, ignoring"); + break; + } //TODO: Verify signature TransactionSignature signature = TransactionSignature.decodeFromBitcoin(TransactionSignature.Type.ECDSA, entry.getData(), true); this.partialSignatures.put(sigPublicKey, signature); @@ -206,10 +217,23 @@ public class PSBTInput { log.debug("Found proprietary input " + Utils.bytesToHex(entry.getKeyData()) + ": " + Utils.bytesToHex(entry.getData())); break; case PSBT_IN_TAP_KEY_SIG: + entry.checkOneByteKey(); this.tapKeyPathSignature = TransactionSignature.decodeFromBitcoin(TransactionSignature.Type.SCHNORR, entry.getData(), true); log.debug("Found input taproot key path signature " + Utils.bytesToHex(entry.getData())); break; + case PSBT_IN_TAP_BIP32_DERIVATION: + entry.checkOneBytePlusXOnlyPubKey(); + ECKey tapPublicKey = ECKey.fromPublicOnly(entry.getKeyData()); + Map> tapKeyDerivations = parseTaprootKeyDerivation(entry.getData()); + if(tapKeyDerivations.isEmpty()) { + log.warn("PSBT provided an invalid taproot key derivation"); + } else { + this.tapDerivedPublicKeys.put(tapPublicKey, tapKeyDerivations); + log.debug("Found input taproot key derivation for key " + Utils.bytesToHex(entry.getKey())); + } + break; case PSBT_IN_TAP_INTERNAL_KEY: + entry.checkOneByteKey(); this.tapInternalKey = ECKey.fromPublicOnly(entry.getData()); log.debug("Found input taproot internal key " + Utils.bytesToHex(entry.getData())); break; @@ -276,6 +300,12 @@ public class PSBTInput { entries.add(populateEntry(PSBT_IN_TAP_KEY_SIG, null, tapKeyPathSignature.encodeToBitcoin())); } + for(Map.Entry>> entry : tapDerivedPublicKeys.entrySet()) { + if(!entry.getValue().isEmpty()) { + entries.add(populateEntry(PSBT_IN_TAP_BIP32_DERIVATION, entry.getKey().getPubKeyXCoord(), serializeTaprootKeyDerivation(Collections.emptyList(), entry.getValue().keySet().iterator().next()))); + } + } + if(tapInternalKey != null) { entries.add(populateEntry(PSBT_IN_TAP_INTERNAL_KEY, null, tapInternalKey.getPubKeyXCoord())); } @@ -318,6 +348,8 @@ public class PSBTInput { tapKeyPathSignature = psbtInput.tapKeyPathSignature; } + tapDerivedPublicKeys.putAll(psbtInput.tapDerivedPublicKeys); + if(psbtInput.tapInternalKey != null) { tapInternalKey = psbtInput.tapInternalKey; } @@ -425,6 +457,14 @@ public class PSBTInput { this.tapKeyPathSignature = tapKeyPathSignature; } + public Map>> getTapDerivedPublicKeys() { + return tapDerivedPublicKeys; + } + + public void setTapDerivedPublicKeys(Map>> tapDerivedPublicKeys) { + this.tapDerivedPublicKeys = tapDerivedPublicKeys; + } + public ECKey getTapInternalKey() { return tapInternalKey; } @@ -517,7 +557,7 @@ public class PSBTInput { Sha256Hash hash = getHashForSignature(signingScript, localSigHash); if(isTaproot() && tapKeyPathSignature != null) { - ECKey outputKey = ScriptType.P2TR.getPublicKeyFromScript(getUtxo().getScript()); + ECKey outputKey = P2TR.getPublicKeyFromScript(getUtxo().getScript()); if(!outputKey.verify(hash, tapKeyPathSignature)) { throw new PSBTSignatureException("Tweaked internal key does not verify against provided taproot keypath signature"); } @@ -637,6 +677,7 @@ public class PSBTInput { witnessScript = null; porCommitment = null; proprietary.clear(); + tapDerivedPublicKeys.clear(); tapKeyPathSignature = null; } diff --git a/src/test/java/com/sparrowwallet/drongo/bip47/PaymentCodeTest.java b/src/test/java/com/sparrowwallet/drongo/bip47/PaymentCodeTest.java index 31c05a9..f8e5809 100644 --- a/src/test/java/com/sparrowwallet/drongo/bip47/PaymentCodeTest.java +++ b/src/test/java/com/sparrowwallet/drongo/bip47/PaymentCodeTest.java @@ -118,7 +118,7 @@ public class PaymentCodeTest { PaymentCode paymentCodeBob = new PaymentCode("PM8TJS2JxQ5ztXUpBBRnpTbcUXbUHy2T1abfrb3KkAAtMEGNbey4oumH7Hc578WgQJhPjBxteQ5GHHToTYHE3A1w6p7tU6KSoFmWBVbFGjKPisZDbP97"); - Wallet aliceBip47Wallet = aliceWallet.addChildWallet(paymentCodeBob, ScriptType.P2PKH); + Wallet aliceBip47Wallet = aliceWallet.addChildWallet(paymentCodeBob, ScriptType.P2PKH, "Alice"); PaymentCode paymentCodeAlice = aliceBip47Wallet.getKeystores().get(0).getPaymentCode(); Assert.assertEquals(aliceWallet.getPaymentCode(), aliceBip47Wallet.getPaymentCode()); @@ -144,7 +144,7 @@ public class PaymentCodeTest { bobWallet.getKeystores().add(Keystore.fromSeed(bobSeed, bobWallet.getScriptType().getDefaultDerivation())); bobWallet.setDefaultPolicy(Policy.getPolicy(PolicyType.SINGLE, ScriptType.P2PKH, bobWallet.getKeystores(), 1)); - Wallet bobBip47Wallet = bobWallet.addChildWallet(paymentCodeAlice, ScriptType.P2PKH); + Wallet bobBip47Wallet = bobWallet.addChildWallet(paymentCodeAlice, ScriptType.P2PKH, "Bob"); Assert.assertEquals(paymentCodeBob.toString(), bobBip47Wallet.getKeystores().get(0).getPaymentCode().toString()); Assert.assertEquals("1ChvUUvht2hUQufHBXF8NgLhW8SwE2ecGV", paymentCodeBob.getNotificationAddress().toString()); From 20f4ac96574dc7bdb811380ff948931663e19c44 Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Wed, 30 Mar 2022 08:55:41 +0200 Subject: [PATCH 113/155] ensure unique stonewall input txids for entire tx (not just per set) --- .../drongo/wallet/StonewallUtxoSelector.java | 35 ++++++++++--------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/StonewallUtxoSelector.java b/src/main/java/com/sparrowwallet/drongo/wallet/StonewallUtxoSelector.java index 64b2f64..0c3330d 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/StonewallUtxoSelector.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/StonewallUtxoSelector.java @@ -21,18 +21,31 @@ public class StonewallUtxoSelector implements UtxoSelector { public List> selectSets(long targetValue, Collection candidates) { long actualTargetValue = targetValue + noInputsFee; - List preferredCandidates = candidates.stream().filter(outputGroup -> outputGroup.getScriptType().equals(preferredScriptType)).collect(Collectors.toList()); + List uniqueCandidates = new ArrayList<>(); + for(OutputGroup candidate : candidates) { + OutputGroup existingTxGroup = getTransactionAlreadySelected(uniqueCandidates, candidate); + if(existingTxGroup != null) { + if(candidate.getValue() > existingTxGroup.getValue()) { + uniqueCandidates.remove(existingTxGroup); + uniqueCandidates.add(candidate); + } + } else { + uniqueCandidates.add(candidate); + } + } + + List preferredCandidates = uniqueCandidates.stream().filter(outputGroup -> outputGroup.getScriptType().equals(preferredScriptType)).collect(Collectors.toList()); List> preferredSets = selectSets(targetValue, preferredCandidates, actualTargetValue); if(!preferredSets.isEmpty()) { return preferredSets; } - return selectSets(targetValue, candidates, actualTargetValue); + return selectSets(targetValue, uniqueCandidates, actualTargetValue); } - private List> selectSets(long targetValue, Collection candidates, long actualTargetValue) { - for(int i = 0; i < 10; i++) { - List randomized = new ArrayList<>(candidates); + private List> selectSets(long targetValue, List uniqueCandidates, long actualTargetValue) { + for(int i = 0; i < 15; i++) { + List randomized = new ArrayList<>(uniqueCandidates); Collections.shuffle(randomized, random); List set1 = new ArrayList<>(); @@ -53,17 +66,7 @@ public class StonewallUtxoSelector implements UtxoSelector { long selectedValue = 0; while(selectedValue <= targetValue && !randomized.isEmpty()) { OutputGroup candidate = randomized.remove(0); - - OutputGroup existingTxGroup = getTransactionAlreadySelected(selectedSet, candidate); - if(existingTxGroup != null) { - if(candidate.getValue() > existingTxGroup.getValue()) { - selectedSet.remove(existingTxGroup); - selectedSet.add(candidate); - } - } else { - selectedSet.add(candidate); - } - + selectedSet.add(candidate); selectedValue = selectedSet.stream().mapToLong(OutputGroup::getEffectiveValue).sum(); } From d9831bdcd0b7c24e7f3ee59c146cf6d9873b42a1 Mon Sep 17 00:00:00 2001 From: satsen <95986745+satsen@users.noreply.github.com> Date: Wed, 13 Apr 2022 13:38:59 +0100 Subject: [PATCH 114/155] Use URI instead of manual parsing --- .../sparrowwallet/drongo/uri/BitcoinURI.java | 23 +++++-------------- 1 file changed, 6 insertions(+), 17 deletions(-) diff --git a/src/main/java/com/sparrowwallet/drongo/uri/BitcoinURI.java b/src/main/java/com/sparrowwallet/drongo/uri/BitcoinURI.java index 055ece0..9ab8e57 100644 --- a/src/main/java/com/sparrowwallet/drongo/uri/BitcoinURI.java +++ b/src/main/java/com/sparrowwallet/drongo/uri/BitcoinURI.java @@ -87,9 +87,7 @@ public class BitcoinURI { * @throws BitcoinURIParseException if the URI is not syntactically or semantically valid. */ public BitcoinURI(String input) throws BitcoinURIParseException { - String scheme = BITCOIN_SCHEME; - - // Attempt to form the URI (fail fast syntax checking to official standards). + // Attempt to parse the URI URI uri; try { uri = new URI(input); @@ -100,23 +98,14 @@ public class BitcoinURI { // URI is formed as bitcoin:
    ? // blockchain.info generates URIs of non-BIP compliant form bitcoin://address?.... - // Remove the bitcoin scheme. - // (Note: getSchemeSpecificPart() is not used as it unescapes the label and parse then fails. - // For instance with : bitcoin:129mVqKUmJ9uwPxKJBnNdABbuaaNfho4Ha?amount=0.06&label=Tom%20%26%20Jerry - // the & (%26) in Tom and Jerry gets interpreted as a separator and the label then gets parsed - // as 'Tom ' instead of 'Tom & Jerry') - String blockchainInfoScheme = scheme + "://"; - String correctScheme = scheme + ":"; - String schemeSpecificPart; - final String inputLc = input.toLowerCase(Locale.US); - if(inputLc.startsWith(blockchainInfoScheme)) { - schemeSpecificPart = input.substring(blockchainInfoScheme.length()); - } else if(inputLc.startsWith(correctScheme)) { - schemeSpecificPart = input.substring(correctScheme.length()); - } else { + if (!BITCOIN_SCHEME.equalsIgnoreCase(uri.getScheme())) { throw new BitcoinURIParseException("Unsupported URI scheme: " + uri.getScheme()); } + String schemeSpecificPart = uri.getRawSchemeSpecificPart().startsWith("//") + ? uri.getRawSchemeSpecificPart().substring(2) + : uri.getRawSchemeSpecificPart(); + // Split off the address from the rest of the query parameters. String[] addressSplitTokens = schemeSpecificPart.split("\\?", 2); if(addressSplitTokens.length == 0) { From 5b3712bfe0d9ba34fbdc931de0032a326804a8d8 Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Tue, 26 Apr 2022 14:57:24 +0200 Subject: [PATCH 115/155] dont add bip32 derived key field to taproot inputs --- src/main/java/com/sparrowwallet/drongo/psbt/PSBTInput.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/sparrowwallet/drongo/psbt/PSBTInput.java b/src/main/java/com/sparrowwallet/drongo/psbt/PSBTInput.java index 71bab98..3b8b0d3 100644 --- a/src/main/java/com/sparrowwallet/drongo/psbt/PSBTInput.java +++ b/src/main/java/com/sparrowwallet/drongo/psbt/PSBTInput.java @@ -76,7 +76,10 @@ public class PSBTInput { this.redeemScript = redeemScript; this.witnessScript = witnessScript; - this.derivedPublicKeys.putAll(derivedPublicKeys); + if(scriptType != P2TR) { + this.derivedPublicKeys.putAll(derivedPublicKeys); + } + this.proprietary.putAll(proprietary); this.tapInternalKey = tapInternalKey; From 9cb95f2f8ca25c23021667f7be47ab9bd9846ce4 Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Wed, 4 May 2022 14:32:24 +0200 Subject: [PATCH 116/155] add psbt taproot output fields, jade wallet --- .../com/sparrowwallet/drongo/psbt/PSBT.java | 22 +++-- .../sparrowwallet/drongo/psbt/PSBTInput.java | 6 +- .../sparrowwallet/drongo/psbt/PSBTOutput.java | 81 +++++++++++++++++-- .../sparrowwallet/drongo/wallet/Wallet.java | 3 + .../drongo/wallet/WalletModel.java | 2 +- .../sparrowwallet/drongo/psbt/PSBTTest.java | 20 +++++ 6 files changed, 119 insertions(+), 15 deletions(-) diff --git a/src/main/java/com/sparrowwallet/drongo/psbt/PSBT.java b/src/main/java/com/sparrowwallet/drongo/psbt/PSBT.java index 77ecef7..6968115 100644 --- a/src/main/java/com/sparrowwallet/drongo/psbt/PSBT.java +++ b/src/main/java/com/sparrowwallet/drongo/psbt/PSBT.java @@ -148,10 +148,11 @@ public class PSBT { for(int outputIndex = 0; outputIndex < outputNodes.size(); outputIndex++) { WalletNode outputNode = outputNodes.get(outputIndex); if(outputNode == null) { - PSBTOutput externalRecipientOutput = new PSBTOutput(null, null, Collections.emptyMap(), Collections.emptyMap()); + PSBTOutput externalRecipientOutput = new PSBTOutput(null, null, null, Collections.emptyMap(), Collections.emptyMap(), null); psbtOutputs.add(externalRecipientOutput); } else { TransactionOutput txOutput = transaction.getOutputs().get(outputIndex); + Wallet recipientWallet = outputNode.getWallet(); //Construct dummy transaction to spend the UTXO created by this wallet's txOutput Transaction transaction = new Transaction(); @@ -168,11 +169,17 @@ public class PSBT { } Map derivedPublicKeys = new LinkedHashMap<>(); - for(Keystore keystore : outputNode.getWallet().getKeystores()) { - derivedPublicKeys.put(keystore.getPubKey(outputNode), keystore.getKeyDerivation().extend(outputNode.getDerivation())); + ECKey tapInternalKey = null; + for(Keystore keystore : recipientWallet.getKeystores()) { + derivedPublicKeys.put(recipientWallet.getScriptType().getOutputKey(keystore.getPubKey(outputNode)), keystore.getKeyDerivation().extend(outputNode.getDerivation())); + + //TODO: Implement Musig for multisig wallets + if(recipientWallet.getScriptType() == ScriptType.P2TR) { + tapInternalKey = keystore.getPubKey(outputNode); + } } - PSBTOutput walletOutput = new PSBTOutput(redeemScript, witnessScript, derivedPublicKeys, Collections.emptyMap()); + PSBTOutput walletOutput = new PSBTOutput(recipientWallet.getScriptType(), redeemScript, witnessScript, derivedPublicKeys, Collections.emptyMap(), tapInternalKey); psbtOutputs.add(walletOutput); } } @@ -476,7 +483,8 @@ public class PSBT { for(PSBTInput psbtInput : getPsbtInputs()) { List inputEntries = psbtInput.getInputEntries(); for(PSBTEntry entry : inputEntries) { - if(includeXpubs || entry.getKeyType() != PSBT_IN_BIP32_DERIVATION) { + if(includeXpubs || (entry.getKeyType() != PSBT_IN_BIP32_DERIVATION && entry.getKeyType() != PSBT_IN_PROPRIETARY + && entry.getKeyType() != PSBT_IN_TAP_INTERNAL_KEY && entry.getKeyType() != PSBT_IN_TAP_BIP32_DERIVATION)) { entry.serializeToStream(baos); } } @@ -486,7 +494,9 @@ public class PSBT { for(PSBTOutput psbtOutput : getPsbtOutputs()) { List outputEntries = psbtOutput.getOutputEntries(); for(PSBTEntry entry : outputEntries) { - if(includeXpubs || (entry.getKeyType() != PSBT_OUT_REDEEM_SCRIPT && entry.getKeyType() != PSBT_OUT_WITNESS_SCRIPT && entry.getKeyType() != PSBT_OUT_BIP32_DERIVATION && entry.getKeyType() != PSBT_OUT_PROPRIETARY)) { + if(includeXpubs || (entry.getKeyType() != PSBT_OUT_REDEEM_SCRIPT && entry.getKeyType() != PSBT_OUT_WITNESS_SCRIPT + && entry.getKeyType() != PSBT_OUT_BIP32_DERIVATION && entry.getKeyType() != PSBT_OUT_PROPRIETARY + && entry.getKeyType() != PSBT_OUT_TAP_INTERNAL_KEY && entry.getKeyType() != PSBT_OUT_TAP_BIP32_DERIVATION)) { entry.serializeToStream(baos); } } diff --git a/src/main/java/com/sparrowwallet/drongo/psbt/PSBTInput.java b/src/main/java/com/sparrowwallet/drongo/psbt/PSBTInput.java index 3b8b0d3..7acc0c1 100644 --- a/src/main/java/com/sparrowwallet/drongo/psbt/PSBTInput.java +++ b/src/main/java/com/sparrowwallet/drongo/psbt/PSBTInput.java @@ -229,10 +229,12 @@ public class PSBTInput { ECKey tapPublicKey = ECKey.fromPublicOnly(entry.getKeyData()); Map> tapKeyDerivations = parseTaprootKeyDerivation(entry.getData()); if(tapKeyDerivations.isEmpty()) { - log.warn("PSBT provided an invalid taproot key derivation"); + log.warn("PSBT provided an invalid input taproot key derivation"); } else { this.tapDerivedPublicKeys.put(tapPublicKey, tapKeyDerivations); - log.debug("Found input taproot key derivation for key " + Utils.bytesToHex(entry.getKey())); + for(KeyDerivation tapKeyDerivation : tapKeyDerivations.keySet()) { + log.debug("Found input taproot key derivation for key " + Utils.bytesToHex(entry.getKeyData()) + " with master fingerprint " + tapKeyDerivation.getMasterFingerprint() + " at path " + tapKeyDerivation.getDerivationPath()); + } } break; case PSBT_IN_TAP_INTERNAL_KEY: diff --git a/src/main/java/com/sparrowwallet/drongo/psbt/PSBTOutput.java b/src/main/java/com/sparrowwallet/drongo/psbt/PSBTOutput.java index af39774..df19680 100644 --- a/src/main/java/com/sparrowwallet/drongo/psbt/PSBTOutput.java +++ b/src/main/java/com/sparrowwallet/drongo/psbt/PSBTOutput.java @@ -4,26 +4,30 @@ import com.sparrowwallet.drongo.KeyDerivation; import com.sparrowwallet.drongo.Utils; import com.sparrowwallet.drongo.crypto.ECKey; import com.sparrowwallet.drongo.protocol.Script; +import com.sparrowwallet.drongo.protocol.ScriptType; +import com.sparrowwallet.drongo.protocol.Sha256Hash; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.ArrayList; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; +import java.util.*; +import static com.sparrowwallet.drongo.protocol.ScriptType.*; import static com.sparrowwallet.drongo.psbt.PSBTEntry.*; public class PSBTOutput { public static final byte PSBT_OUT_REDEEM_SCRIPT = 0x00; public static final byte PSBT_OUT_WITNESS_SCRIPT = 0x01; public static final byte PSBT_OUT_BIP32_DERIVATION = 0x02; + public static final byte PSBT_OUT_TAP_INTERNAL_KEY = 0x05; + public static final byte PSBT_OUT_TAP_BIP32_DERIVATION = 0x07; public static final byte PSBT_OUT_PROPRIETARY = (byte)0xfc; private Script redeemScript; private Script witnessScript; private final Map derivedPublicKeys = new LinkedHashMap<>(); private final Map proprietary = new LinkedHashMap<>(); + private Map>> tapDerivedPublicKeys = new LinkedHashMap<>(); + private ECKey tapInternalKey; private static final Logger log = LoggerFactory.getLogger(PSBTOutput.class); @@ -31,11 +35,22 @@ public class PSBTOutput { //empty constructor } - PSBTOutput(Script redeemScript, Script witnessScript, Map derivedPublicKeys, Map proprietary) { + PSBTOutput(ScriptType scriptType, Script redeemScript, Script witnessScript, Map derivedPublicKeys, Map proprietary, ECKey tapInternalKey) { this.redeemScript = redeemScript; this.witnessScript = witnessScript; - this.derivedPublicKeys.putAll(derivedPublicKeys); + + if(scriptType != P2TR) { + this.derivedPublicKeys.putAll(derivedPublicKeys); + } + this.proprietary.putAll(proprietary); + + this.tapInternalKey = tapInternalKey; + + if(tapInternalKey != null && !derivedPublicKeys.values().isEmpty()) { + KeyDerivation tapKeyDerivation = derivedPublicKeys.values().iterator().next(); + tapDerivedPublicKeys.put(tapInternalKey, Map.of(tapKeyDerivation, Collections.emptyList())); + } } PSBTOutput(List outputEntries) throws PSBTParseException { @@ -64,6 +79,24 @@ public class PSBTOutput { proprietary.put(Utils.bytesToHex(entry.getKeyData()), Utils.bytesToHex(entry.getData())); log.debug("Found proprietary output " + Utils.bytesToHex(entry.getKeyData()) + ": " + Utils.bytesToHex(entry.getData())); break; + case PSBT_OUT_TAP_INTERNAL_KEY: + entry.checkOneByteKey(); + this.tapInternalKey = ECKey.fromPublicOnly(entry.getData()); + log.debug("Found output taproot internal key " + Utils.bytesToHex(entry.getData())); + break; + case PSBT_OUT_TAP_BIP32_DERIVATION: + entry.checkOneBytePlusXOnlyPubKey(); + ECKey tapPublicKey = ECKey.fromPublicOnly(entry.getKeyData()); + Map> tapKeyDerivations = parseTaprootKeyDerivation(entry.getData()); + if(tapKeyDerivations.isEmpty()) { + log.warn("PSBT provided an invalid output taproot key derivation"); + } else { + this.tapDerivedPublicKeys.put(tapPublicKey, tapKeyDerivations); + for(KeyDerivation tapKeyDerivation : tapKeyDerivations.keySet()) { + log.debug("Found output taproot key derivation for key " + Utils.bytesToHex(entry.getKeyData()) + " with master fingerprint " + tapKeyDerivation.getMasterFingerprint() + " at path " + tapKeyDerivation.getDerivationPath()); + } + } + break; default: log.warn("PSBT output not recognized key type: " + entry.getKeyType()); } @@ -89,6 +122,16 @@ public class PSBTOutput { entries.add(populateEntry(PSBT_OUT_PROPRIETARY, Utils.hexToBytes(entry.getKey()), Utils.hexToBytes(entry.getValue()))); } + for(Map.Entry>> entry : tapDerivedPublicKeys.entrySet()) { + if(!entry.getValue().isEmpty()) { + entries.add(populateEntry(PSBT_OUT_TAP_BIP32_DERIVATION, entry.getKey().getPubKeyXCoord(), serializeTaprootKeyDerivation(Collections.emptyList(), entry.getValue().keySet().iterator().next()))); + } + } + + if(tapInternalKey != null) { + entries.add(populateEntry(PSBT_OUT_TAP_INTERNAL_KEY, null, tapInternalKey.getPubKeyXCoord())); + } + return entries; } @@ -103,6 +146,12 @@ public class PSBTOutput { derivedPublicKeys.putAll(psbtOutput.derivedPublicKeys); proprietary.putAll(psbtOutput.proprietary); + + tapDerivedPublicKeys.putAll(psbtOutput.tapDerivedPublicKeys); + + if(psbtOutput.tapInternalKey != null) { + tapInternalKey = psbtOutput.tapInternalKey; + } } public Script getRedeemScript() { @@ -132,4 +181,24 @@ public class PSBTOutput { public Map getProprietary() { return proprietary; } + + public Map>> getTapDerivedPublicKeys() { + return tapDerivedPublicKeys; + } + + public void setTapDerivedPublicKeys(Map>> tapDerivedPublicKeys) { + this.tapDerivedPublicKeys = tapDerivedPublicKeys; + } + + public ECKey getTapInternalKey() { + return tapInternalKey; + } + + public void setTapInternalKey(ECKey tapInternalKey) { + this.tapInternalKey = tapInternalKey; + } + + public void clearNonFinalFields() { + tapDerivedPublicKeys.clear(); + } } diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java index 19ce824..b21d0b3 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java @@ -12,6 +12,7 @@ import com.sparrowwallet.drongo.policy.PolicyType; import com.sparrowwallet.drongo.protocol.*; import com.sparrowwallet.drongo.psbt.PSBT; import com.sparrowwallet.drongo.psbt.PSBTInput; +import com.sparrowwallet.drongo.psbt.PSBTOutput; import java.nio.charset.StandardCharsets; import java.util.*; @@ -1557,6 +1558,8 @@ public class Wallet extends Persistable implements Comparable { psbtInput.clearNonFinalFields(); } } + + psbt.getPsbtOutputs().forEach(PSBTOutput::clearNonFinalFields); } public BitcoinUnit getAutoUnit() { diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/WalletModel.java b/src/main/java/com/sparrowwallet/drongo/wallet/WalletModel.java index e9b5379..db4bfdf 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/WalletModel.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/WalletModel.java @@ -1,7 +1,7 @@ package com.sparrowwallet.drongo.wallet; public enum WalletModel { - SEED, SPARROW, BITCOIN_CORE, ELECTRUM, TREZOR_1, TREZOR_T, COLDCARD, LEDGER_NANO_S, LEDGER_NANO_X, DIGITALBITBOX_01, KEEPKEY, SPECTER_DESKTOP, COBO_VAULT, BITBOX_02, SPECTER_DIY, PASSPORT, BLUE_WALLET, KEYSTONE, SEEDSIGNER, CARAVAN, GORDIAN_SEED_TOOL; + SEED, SPARROW, BITCOIN_CORE, ELECTRUM, TREZOR_1, TREZOR_T, COLDCARD, LEDGER_NANO_S, LEDGER_NANO_X, DIGITALBITBOX_01, KEEPKEY, SPECTER_DESKTOP, COBO_VAULT, BITBOX_02, SPECTER_DIY, PASSPORT, BLUE_WALLET, KEYSTONE, SEEDSIGNER, CARAVAN, GORDIAN_SEED_TOOL, JADE; public static WalletModel getModel(String model) { return valueOf(model.toUpperCase()); diff --git a/src/test/java/com/sparrowwallet/drongo/psbt/PSBTTest.java b/src/test/java/com/sparrowwallet/drongo/psbt/PSBTTest.java index dd9ff2f..04f8f5b 100644 --- a/src/test/java/com/sparrowwallet/drongo/psbt/PSBTTest.java +++ b/src/test/java/com/sparrowwallet/drongo/psbt/PSBTTest.java @@ -11,6 +11,9 @@ import org.junit.After; import org.junit.Assert; import org.junit.Test; +import java.util.List; +import java.util.Map; + public class PSBTTest { @Test(expected = PSBTParseException.class) @@ -379,6 +382,23 @@ public class PSBTTest { Assert.assertFalse(PSBT.isPSBT("x")); } + @Test + public void testTaproot() throws PSBTParseException { + Network.set(Network.TESTNET); + String strSignedPsbt = "cHNidP8BAH0CAAAAAdPUSBYKaQKOqAMgU2IcGuM6z7JtbkLe69OmYZoa4UxYAAAAAADmdQAAAp4CAAAAAAAAFgAUg+/zyGWbtKbIJb8ZasbGYDtItZhgrgEAAAAAACJRIJMQKWeQsI/WiRS+lmeeyeJaKFVnlVoBtXeuGTO7XIbrAAAAAE8BBDWHzwM27GqkgAAAAO1YZge2AP67ozhdoF9wgg2hpJw1jbVEXLKfxRQUNGEIAlog/wK83w7jxD37prhWrPenLxjGAJzkJKrj6h0ZPK8WED/ZeB1WAACAAQAAgAAAAIAAAQCJAgAAAAGBuBuu5OIheS4SKtYJufScCJDTWWLopBoXtFWhPDuRWQEAAAAA/f///wKNsQEAAAAAACJRIAjXFSnHwcD+J/obgd9CxVneHsUyFKM9xU7NY5K3DgCxHwIAAAAAAAAiUSAhUe66hJMCB1esHqXtxRVJHmviQ4ZjzFIwDWDPk+1KY6VyIQABASuNsQEAAAAAACJRIAjXFSnHwcD+J/obgd9CxVneHsUyFKM9xU7NY5K3DgCxAQMEAAAAAAETQCG/ZGuefjDVqBhmgVEuV1HbdxoZKDDWWTvTUrq6MJreRzj22k/WcFni6yPn9PGZkptZSNx9waf8ouP28ogJz24hFnRZPMvN82XI+lnim7dRKwFgpHnqiDoMGnIoFoSQRX7bGQA/2XgdVgAAgAEAAIAAAACAAQAAAAIAAAABFyB0WTzLzfNlyPpZ4pu3USsBYKR56og6DBpyKBaEkEV+2wAAIQflpK6JYWolG3K2DU7FU3hlkwSdU/69bglhZxaprqSvyxkAP9l4HVYAAIABAACAAAAAgAEAAAADAAAAAQUg5aSuiWFqJRtytg1OxVN4ZZMEnVP+vW4JYWcWqa6kr8sA"; + PSBT psbt = PSBT.fromString(strSignedPsbt); + + Assert.assertEquals(0, psbt.getPsbtInputs().get(0).getDerivedPublicKeys().size()); + Assert.assertEquals("74593ccbcdf365c8fa59e29bb7512b0160a479ea883a0c1a7228168490457edb", Utils.bytesToHex(psbt.getPsbtInputs().get(0).getTapDerivedPublicKeys().keySet().iterator().next().getPubKeyXCoord())); + Map> tapInKeyDerivations = psbt.getPsbtInputs().get(0).getTapDerivedPublicKeys().values().iterator().next(); + Assert.assertEquals("3fd9781d", tapInKeyDerivations.keySet().iterator().next().getMasterFingerprint()); + + Assert.assertEquals(0, psbt.getPsbtOutputs().get(0).getDerivedPublicKeys().size()); + Assert.assertEquals("e5a4ae89616a251b72b60d4ec553786593049d53febd6e09616716a9aea4afcb", Utils.bytesToHex(psbt.getPsbtOutputs().get(1).getTapDerivedPublicKeys().keySet().iterator().next().getPubKeyXCoord())); + Map> tapOutKeyDerivations = psbt.getPsbtOutputs().get(1).getTapDerivedPublicKeys().values().iterator().next(); + Assert.assertEquals("3fd9781d", tapOutKeyDerivations.keySet().iterator().next().getMasterFingerprint()); + } + @After public void tearDown() throws Exception { Network.set(null); From ba8692450335f2e5293ddd3951a394244315803f Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Fri, 6 May 2022 17:34:00 +0200 Subject: [PATCH 117/155] add native libraries for aarch64 --- build.gradle | 4 +++- src/main/java/module-info.java | 2 +- .../java/org/bitcoin/Secp256k1Context.java | 5 ++++- .../native/osx/aarch64/libsecp256k1.dylib | Bin 0 -> 228881 bytes 4 files changed, 8 insertions(+), 3 deletions(-) create mode 100755 src/main/resources/native/osx/aarch64/libsecp256k1.dylib diff --git a/build.gradle b/build.gradle index 9345192..ba4adeb 100644 --- a/build.gradle +++ b/build.gradle @@ -44,10 +44,12 @@ dependencies { implementation ('org.bouncycastle:bcprov-jdk15on:1.64') { exclude group: 'org.hamcrest', module: 'hamcrest-core' } - implementation ('de.mkammerer:argon2-jvm:2.7') { + implementation ('de.mkammerer:argon2-jvm:2.11') { exclude group: 'org.hamcrest', module: 'hamcrest-core' exclude group: 'junit', module: 'junit' + exclude group: 'net.java.dev.jna', module: 'jna' } + implementation ('net.java.dev.jna:jna:5.8.0') implementation ('ch.qos.logback:logback-classic:1.2.8') { exclude group: 'org.hamcrest', module: 'hamcrest-core' exclude group: 'org.slf4j' diff --git a/src/main/java/module-info.java b/src/main/java/module-info.java index 49bb37b..8e48428 100644 --- a/src/main/java/module-info.java +++ b/src/main/java/module-info.java @@ -1,6 +1,6 @@ open module com.sparrowwallet.drongo { requires org.bouncycastle.provider; - requires de.mkammerer.argon2; + requires de.mkammerer.argon2.nolibs; requires org.slf4j; requires logback.core; requires logback.classic; diff --git a/src/main/java/org/bitcoin/Secp256k1Context.java b/src/main/java/org/bitcoin/Secp256k1Context.java index 2e8909e..39494b5 100644 --- a/src/main/java/org/bitcoin/Secp256k1Context.java +++ b/src/main/java/org/bitcoin/Secp256k1Context.java @@ -35,7 +35,10 @@ public class Secp256k1Context { private static boolean loadLibrary() { try { String osName = System.getProperty("os.name"); - if(osName.startsWith("Mac")) { + String osArch = System.getProperty("os.arch"); + if(osName.startsWith("Mac") && osArch.equals("aarch64")) { + NativeUtils.loadLibraryFromJar("/native/osx/aarch64/libsecp256k1.dylib"); + } else if(osName.startsWith("Mac")) { NativeUtils.loadLibraryFromJar("/native/osx/x64/libsecp256k1.dylib"); } else if(osName.startsWith("Windows")) { NativeUtils.loadLibraryFromJar("/native/windows/x64/libsecp256k1-0.dll"); diff --git a/src/main/resources/native/osx/aarch64/libsecp256k1.dylib b/src/main/resources/native/osx/aarch64/libsecp256k1.dylib new file mode 100755 index 0000000000000000000000000000000000000000..02aa2ff44439e9cb71e5f64eae2ab9d6205745ea GIT binary patch literal 228881 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[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 Vm7u{!LlKG`HhplGBl2cU@jr5>UDW^p literal 0 HcmV?d00001 From eddd6406efc20b83e659d59faa16189417b0f5ed Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Thu, 12 May 2022 10:56:00 +0200 Subject: [PATCH 118/155] consider spent mempool outputs when checking max spendable amount for rbf txes --- src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java index b21d0b3..cfde89e 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java @@ -967,7 +967,7 @@ public class Wallet extends Persistable implements Comparable { throw new IllegalArgumentException("Use an input fee rate of 1 sat/vB when using a defined fee amount so UTXO selectors overestimate effective value"); } - long maxSpendableAmt = getMaxSpendable(payments.stream().map(Payment::getAddress).collect(Collectors.toList()), feeRate); + long maxSpendableAmt = getMaxSpendable(payments.stream().map(Payment::getAddress).collect(Collectors.toList()), feeRate, includeSpentMempoolOutputs); if(maxSpendableAmt < 0) { throw new InsufficientFundsException("Not enough combined value in all available UTXOs to send a transaction to the provided addresses at this fee rate"); } @@ -1282,11 +1282,11 @@ public class Wallet extends Persistable implements Comparable { * @param feeRate the fee rate in sats/vB * @return the maximum spendable amount (can be negative if the fee is higher than the combined UTXO value) */ - public long getMaxSpendable(List

    paymentAddresses, double feeRate) { + public long getMaxSpendable(List
    paymentAddresses, double feeRate, boolean includeSpentMempoolOutputs) { long maxInputValue = 0; Transaction transaction = new Transaction(); - for(Map.Entry utxo : getWalletUtxos().entrySet()) { + for(Map.Entry utxo : getWalletUtxos(includeSpentMempoolOutputs).entrySet()) { int inputWeightUnits = utxo.getValue().getWallet().getInputWeightUnits(); long minInputValue = (long)Math.ceil(feeRate * inputWeightUnits / WITNESS_SCALE_FACTOR); if(utxo.getKey().getValue() > minInputValue) { From 38deacaeec757acaaaedada7c17e9338564cb389 Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Tue, 17 May 2022 08:02:24 +0200 Subject: [PATCH 119/155] add support for seedqr parsing --- .../sparrowwallet/drongo/wallet/SeedQR.java | 58 +++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 src/main/java/com/sparrowwallet/drongo/wallet/SeedQR.java diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/SeedQR.java b/src/main/java/com/sparrowwallet/drongo/wallet/SeedQR.java new file mode 100644 index 0000000..30231cd --- /dev/null +++ b/src/main/java/com/sparrowwallet/drongo/wallet/SeedQR.java @@ -0,0 +1,58 @@ +package com.sparrowwallet.drongo.wallet; + +import com.sparrowwallet.drongo.Utils; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.IntStream; + +public class SeedQR { + public static DeterministicSeed getSeed(String seedQr) { + if(seedQr.length() < 48 || seedQr.length() > 96 || seedQr.length() % 4 > 0) { + throw new IllegalArgumentException("Invalid SeedQR length: " + seedQr.length()); + } + + if(!seedQr.chars().allMatch(c -> c >= '0' && c <= '9')) { + throw new IllegalArgumentException("SeedQR contains non-digit characters: " + seedQr); + } + + List indexes = IntStream.iterate(0, i -> i + 4).limit((int)Math.ceil(seedQr.length() / 4.0)) + .mapToObj(i -> seedQr.substring(i, Math.min(i + 4, seedQr.length()))) + .map(Integer::parseInt) + .collect(Collectors.toList()); + + List words = new ArrayList<>(indexes.size()); + for(Integer index : indexes) { + words.add(Bip39MnemonicCode.INSTANCE.getWordList().get(index)); + } + + return new DeterministicSeed(words, null, System.currentTimeMillis(), DeterministicSeed.Type.BIP39); + } + + public static DeterministicSeed getSeed(byte[] compactSeedQr) { + if(compactSeedQr[0] != 0x41 && compactSeedQr[0] != 0x42) { + throw new IllegalArgumentException("Invalid CompactSeedQR header"); + } + + if(compactSeedQr.length < 19) { + throw new IllegalArgumentException("Invalid CompactSeedQR length"); + } + + String qrHex = Utils.bytesToHex(compactSeedQr); + String seedHex; + if(qrHex.endsWith("0ec")) { + seedHex = qrHex.substring(3, qrHex.length() - 3); + } else { + seedHex = qrHex.substring(3, qrHex.length() - 1); + } + + byte[] seed = Utils.hexToBytes(seedHex); + + if(seed.length < 16 || seed.length > 32 || seed.length % 4 > 0) { + throw new IllegalArgumentException("Invalid CompactSeedQR length: " + compactSeedQr.length); + } + + return new DeterministicSeed(seed, null, System.currentTimeMillis()); + } +} From d24243ce20a9d10f77cfe95f172940743a94a8a7 Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Thu, 19 May 2022 12:29:56 +0200 Subject: [PATCH 120/155] set lower bound on bip47 account index --- src/main/java/com/sparrowwallet/drongo/KeyDerivation.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/sparrowwallet/drongo/KeyDerivation.java b/src/main/java/com/sparrowwallet/drongo/KeyDerivation.java index 2db24be..3d6020b 100644 --- a/src/main/java/com/sparrowwallet/drongo/KeyDerivation.java +++ b/src/main/java/com/sparrowwallet/drongo/KeyDerivation.java @@ -96,7 +96,7 @@ public class KeyDerivation { } public static List getBip47Derivation(int account) { - return List.of(new ChildNumber(47, true), new ChildNumber(Network.get() == Network.MAINNET ? 0 : 1, true), new ChildNumber(account, true)); + return List.of(new ChildNumber(47, true), new ChildNumber(Network.get() == Network.MAINNET ? 0 : 1, true), new ChildNumber(Math.max(0, account), true)); } public KeyDerivation copy() { From 8e50815a3faca8ddc03bf20935ee9ee13b897066 Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Thu, 19 May 2022 16:34:14 +0200 Subject: [PATCH 121/155] preserve txo status when updating node outputs --- src/main/java/com/sparrowwallet/drongo/wallet/WalletNode.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/WalletNode.java b/src/main/java/com/sparrowwallet/drongo/wallet/WalletNode.java index af1fe5d..538dd58 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/WalletNode.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/WalletNode.java @@ -138,6 +138,8 @@ public class WalletNode extends Persistable implements Comparable { if(!transactionOutputs.isEmpty()) { Optional optionalLabel = transactionOutputs.stream().filter(oldTxo -> oldTxo.getHash().equals(txo.getHash()) && oldTxo.getIndex() == txo.getIndex()).map(BlockTransactionHash::getLabel).filter(Objects::nonNull).findFirst(); optionalLabel.ifPresent(txo::setLabel); + Optional optionalStatus = transactionOutputs.stream().filter(oldTxo -> oldTxo.getHash().equals(txo.getHash()) && oldTxo.getIndex() == txo.getIndex()).map(BlockTransactionHashIndex::getStatus).filter(Objects::nonNull).findFirst(); + optionalStatus.ifPresent(txo::setStatus); } if(!wallet.getDetachedLabels().isEmpty()) { From a3ec868b75752b09c6b67c77efd22979bdd7e9b6 Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Tue, 24 May 2022 10:43:49 +0200 Subject: [PATCH 122/155] add ledger nano s plus wallet model --- .../java/com/sparrowwallet/drongo/wallet/WalletModel.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/WalletModel.java b/src/main/java/com/sparrowwallet/drongo/wallet/WalletModel.java index db4bfdf..b73e442 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/WalletModel.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/WalletModel.java @@ -1,7 +1,7 @@ package com.sparrowwallet.drongo.wallet; public enum WalletModel { - SEED, SPARROW, BITCOIN_CORE, ELECTRUM, TREZOR_1, TREZOR_T, COLDCARD, LEDGER_NANO_S, LEDGER_NANO_X, DIGITALBITBOX_01, KEEPKEY, SPECTER_DESKTOP, COBO_VAULT, BITBOX_02, SPECTER_DIY, PASSPORT, BLUE_WALLET, KEYSTONE, SEEDSIGNER, CARAVAN, GORDIAN_SEED_TOOL, JADE; + SEED, SPARROW, BITCOIN_CORE, ELECTRUM, TREZOR_1, TREZOR_T, COLDCARD, LEDGER_NANO_S, LEDGER_NANO_X, DIGITALBITBOX_01, KEEPKEY, SPECTER_DESKTOP, COBO_VAULT, BITBOX_02, SPECTER_DIY, PASSPORT, BLUE_WALLET, KEYSTONE, SEEDSIGNER, CARAVAN, GORDIAN_SEED_TOOL, JADE, LEDGER_NANO_S_PLUS; public static WalletModel getModel(String model) { return valueOf(model.toUpperCase()); @@ -12,7 +12,7 @@ public enum WalletModel { return "trezor"; } - if(this == LEDGER_NANO_S || this == LEDGER_NANO_X) { + if(this == LEDGER_NANO_S || this == LEDGER_NANO_X || this == LEDGER_NANO_S_PLUS) { return "ledger"; } From 7535c876bad20a82b0ef4635e97d1528d58c4ba7 Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Wed, 25 May 2022 16:14:26 +0200 Subject: [PATCH 123/155] ensure dummy y value of taproot internal key is consistent --- src/main/java/com/sparrowwallet/drongo/psbt/PSBTInput.java | 4 ++-- src/main/java/com/sparrowwallet/drongo/psbt/PSBTOutput.java | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/sparrowwallet/drongo/psbt/PSBTInput.java b/src/main/java/com/sparrowwallet/drongo/psbt/PSBTInput.java index 7acc0c1..66110ea 100644 --- a/src/main/java/com/sparrowwallet/drongo/psbt/PSBTInput.java +++ b/src/main/java/com/sparrowwallet/drongo/psbt/PSBTInput.java @@ -82,11 +82,11 @@ public class PSBTInput { this.proprietary.putAll(proprietary); - this.tapInternalKey = tapInternalKey; + this.tapInternalKey = tapInternalKey == null ? null : ECKey.fromPublicOnly(tapInternalKey.getPubKeyXCoord()); if(tapInternalKey != null && !derivedPublicKeys.values().isEmpty()) { KeyDerivation tapKeyDerivation = derivedPublicKeys.values().iterator().next(); - tapDerivedPublicKeys.put(tapInternalKey, Map.of(tapKeyDerivation, Collections.emptyList())); + tapDerivedPublicKeys.put(this.tapInternalKey, Map.of(tapKeyDerivation, Collections.emptyList())); } this.sigHash = getDefaultSigHash(); diff --git a/src/main/java/com/sparrowwallet/drongo/psbt/PSBTOutput.java b/src/main/java/com/sparrowwallet/drongo/psbt/PSBTOutput.java index df19680..fb10a71 100644 --- a/src/main/java/com/sparrowwallet/drongo/psbt/PSBTOutput.java +++ b/src/main/java/com/sparrowwallet/drongo/psbt/PSBTOutput.java @@ -45,11 +45,11 @@ public class PSBTOutput { this.proprietary.putAll(proprietary); - this.tapInternalKey = tapInternalKey; + this.tapInternalKey = tapInternalKey == null ? null : ECKey.fromPublicOnly(tapInternalKey.getPubKeyXCoord()); if(tapInternalKey != null && !derivedPublicKeys.values().isEmpty()) { KeyDerivation tapKeyDerivation = derivedPublicKeys.values().iterator().next(); - tapDerivedPublicKeys.put(tapInternalKey, Map.of(tapKeyDerivation, Collections.emptyList())); + tapDerivedPublicKeys.put(this.tapInternalKey, Map.of(tapKeyDerivation, Collections.emptyList())); } } From 7f2c5a5a59c046816b9809fc629305c7d4cfe932 Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Mon, 30 May 2022 16:27:55 +0200 Subject: [PATCH 124/155] rename taproot sighash default and avoid conflation with sighash all --- .../com/sparrowwallet/drongo/protocol/SigHash.java | 9 +++++++-- .../drongo/protocol/TransactionSignature.java | 12 ++++++++---- .../com/sparrowwallet/drongo/psbt/PSBTInput.java | 2 +- .../java/com/sparrowwallet/drongo/wallet/Wallet.java | 2 +- .../drongo/protocol/TransactionTest.java | 4 ++-- 5 files changed, 19 insertions(+), 10 deletions(-) diff --git a/src/main/java/com/sparrowwallet/drongo/protocol/SigHash.java b/src/main/java/com/sparrowwallet/drongo/protocol/SigHash.java index 9d5c44f..de060df 100644 --- a/src/main/java/com/sparrowwallet/drongo/protocol/SigHash.java +++ b/src/main/java/com/sparrowwallet/drongo/protocol/SigHash.java @@ -1,22 +1,27 @@ package com.sparrowwallet.drongo.protocol; +import java.util.List; + /** * These constants are a part of a scriptSig signature on the inputs. They define the details of how a * transaction can be redeemed, specifically, they control how the hash of the transaction is calculated. */ public enum SigHash { - ALL("All (Recommended)", (byte)1), + ALL("All", (byte)1), NONE("None", (byte)2), SINGLE("Single", (byte)3), ANYONECANPAY("Anyone Can Pay", (byte)0x80), // Caution: Using this type in isolation is non-standard. Treated similar to ANYONECANPAY_ALL. ANYONECANPAY_ALL("All + Anyone Can Pay", (byte)0x81), ANYONECANPAY_NONE("None + Anyone Can Pay", (byte)0x82), ANYONECANPAY_SINGLE("Single + Anyone Can Pay", (byte)0x83), - ALL_TAPROOT("All (Taproot)", (byte)0); + DEFAULT("Default", (byte)0); private final String name; public final byte value; + public static final List LEGACY_SIGNING_TYPES = List.of(ALL, NONE, SINGLE, ANYONECANPAY_ALL, ANYONECANPAY_NONE, ANYONECANPAY_SINGLE); + public static final List TAPROOT_SIGNING_TYPES = List.of(DEFAULT, ALL, NONE, SINGLE, ANYONECANPAY_ALL, ANYONECANPAY_NONE, ANYONECANPAY_SINGLE); + private SigHash(final String name, final byte value) { this.name = name; this.value = value; diff --git a/src/main/java/com/sparrowwallet/drongo/protocol/TransactionSignature.java b/src/main/java/com/sparrowwallet/drongo/protocol/TransactionSignature.java index b15f722..e9b173e 100644 --- a/src/main/java/com/sparrowwallet/drongo/protocol/TransactionSignature.java +++ b/src/main/java/com/sparrowwallet/drongo/protocol/TransactionSignature.java @@ -24,7 +24,7 @@ public class TransactionSignature { /** Constructs a signature with the given components of the given type and SIGHASH_ALL. */ public TransactionSignature(BigInteger r, BigInteger s, Type type) { - this(r, s, type, type == Type.ECDSA ? SigHash.ALL.value : SigHash.ALL_TAPROOT.value); + this(r, s, type, type == Type.ECDSA ? SigHash.ALL.value : SigHash.DEFAULT.value); } /** Constructs a transaction signature based on the ECDSA signature. */ @@ -60,6 +60,10 @@ public class TransactionSignature { } private SigHash getSigHash() { + if(sighashFlags == SigHash.DEFAULT.byteValue()) { + return SigHash.DEFAULT; + } + boolean anyoneCanPay = anyoneCanPay(); final int mode = sighashFlags & 0x1f; if (mode == SigHash.NONE.value) { @@ -86,10 +90,10 @@ public class TransactionSignature { throw new RuntimeException(e); // Cannot happen. } } else if(schnorrSignature != null) { - SigHash sigHash = getSigHash(); //Note this will return Sighash.ALL for Sighash.ALL_TAPROOT as well - ByteBuffer buffer = ByteBuffer.allocate(sigHash == SigHash.ALL ? 64 : 65); + SigHash sigHash = getSigHash(); + ByteBuffer buffer = ByteBuffer.allocate(sigHash == SigHash.DEFAULT ? 64 : 65); buffer.put(schnorrSignature.encode()); - if(sigHash != SigHash.ALL) { + if(sigHash != SigHash.DEFAULT) { buffer.put(sighashFlags); } return buffer.array(); diff --git a/src/main/java/com/sparrowwallet/drongo/psbt/PSBTInput.java b/src/main/java/com/sparrowwallet/drongo/psbt/PSBTInput.java index 66110ea..dbc0145 100644 --- a/src/main/java/com/sparrowwallet/drongo/psbt/PSBTInput.java +++ b/src/main/java/com/sparrowwallet/drongo/psbt/PSBTInput.java @@ -513,7 +513,7 @@ public class PSBTInput { private SigHash getDefaultSigHash() { if(isTaproot()) { - return SigHash.ALL_TAPROOT; + return SigHash.DEFAULT; } return SigHash.ALL; diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java index cfde89e..6cc1085 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java @@ -1365,7 +1365,7 @@ public class Wallet extends Persistable implements Comparable { Sha256Hash hash; if(signingWallet.getScriptType() == P2TR) { List spentOutputs = transaction.getInputs().stream().map(input -> signingWallet.transactions.get(input.getOutpoint().getHash()).getTransaction().getOutputs().get((int)input.getOutpoint().getIndex())).collect(Collectors.toList()); - hash = transaction.hashForTaprootSignature(spentOutputs, txInput.getIndex(), !P2TR.isScriptType(signingScript), signingScript, SigHash.ALL_TAPROOT, null); + hash = transaction.hashForTaprootSignature(spentOutputs, txInput.getIndex(), !P2TR.isScriptType(signingScript), signingScript, SigHash.DEFAULT, null); } else if(txInput.hasWitness()) { hash = transaction.hashForWitnessSignature(txInput.getIndex(), signingScript, spentTxo.getValue(), SigHash.ALL); } else { diff --git a/src/test/java/com/sparrowwallet/drongo/protocol/TransactionTest.java b/src/test/java/com/sparrowwallet/drongo/protocol/TransactionTest.java index dcc266e..9934020 100644 --- a/src/test/java/com/sparrowwallet/drongo/protocol/TransactionTest.java +++ b/src/test/java/com/sparrowwallet/drongo/protocol/TransactionTest.java @@ -494,13 +494,13 @@ public class TransactionTest { Transaction tx = new Transaction(Utils.hexToBytes("02000000000101786ed355f998b98f8ef8ef2acf461577325cf170a9133d48a17aba957eb97ff00000000000ffffffff0100e1f50500000000220020693a94699e6e41ab302fd623a9bf5a5b2d6606cbfb35c550d1cb4300451356a102473044022004cc317c20eb9e372cb0e640f51eb2b8311616125321b11dbaa5671db5a3ca2a02207ae3d2771b565be98ae56e21045b9629c94b6ca8f4e3932260e54d4f0e2016b30121032da1692a41a61ad14f3795b31d33431abf8d6ee161b997d004c26a37bc20083500000000")); Transaction spendingTx = new Transaction(Utils.hexToBytes("01000000011af4dca4a6bc6da092edca5390355891da9bbe76d2be1c04d067ec9c3a3d22b10000000000000000000180f0fa0200000000160014a3bcb5f272025cc66dc42e7518a5846bd60a9c9600000000")); - Sha256Hash hash = spendingTx.hashForTaprootSignature(tx.getOutputs(), 0, false, null, SigHash.ALL_TAPROOT, null); + Sha256Hash hash = spendingTx.hashForTaprootSignature(tx.getOutputs(), 0, false, null, SigHash.DEFAULT, null); ECKey privateKey = ECKey.fromPrivate(Utils.hexToBytes("d9bc817b92916a24b87d25dc48ef466b4fcd6c89cf90afbc17cba40eb8b91330")); SchnorrSignature sig = privateKey.signSchnorr(hash); Assert.assertEquals("7b04f59bc8f5c2c33c9b8acbf94743de74cc25a6052b52ff61a516f7c5ca19cc68345ba99b354f22bfaf5c04de395b9223f3bf0a5c351fc1cc68c224f4e5b202", Utils.bytesToHex(sig.encode())); ECKey pubKey = ECKey.fromPublicOnly(privateKey); - Assert.assertTrue(pubKey.verify(hash, new TransactionSignature(sig, SigHash.ALL_TAPROOT))); + Assert.assertTrue(pubKey.verify(hash, new TransactionSignature(sig, SigHash.DEFAULT))); } } From 1a20e0381c8961d51e5ccef04e3d47d41cec9388 Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Mon, 6 Jun 2022 13:38:06 +0200 Subject: [PATCH 125/155] always find node for first input when retrieving historical notification txes --- src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java index 6cc1085..504c6f2 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java @@ -288,8 +288,10 @@ public class Wallet extends Persistable implements Comparable { if(txoEntry.getKey().isSpent()) { BlockTransaction blockTransaction = getWalletTransaction(txoEntry.getKey().getSpentBy().getHash()); if(blockTransaction != null) { + TransactionInput txInput0 = blockTransaction.getTransaction().getInputs().get(0); for(TransactionOutput txOutput : blockTransaction.getTransaction().getOutputs()) { - if(notificationAddress.equals(txOutput.getScript().getToAddress())) { + if(notificationAddress.equals(txOutput.getScript().getToAddress()) + && txoEntry.getValue().getTransactionOutputs().stream().anyMatch(ref -> ref.getHash().equals(txInput0.getOutpoint().getHash()) && ref.getIndex() == txInput0.getOutpoint().getIndex())) { try { PaymentCode.getOpReturnData(blockTransaction.getTransaction()); return Map.of(blockTransaction, txoEntry.getValue()); From d05ec39df7d7c8d23f61f39338c467b9507f0aaa Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Thu, 7 Jul 2022 11:08:39 +0200 Subject: [PATCH 126/155] optimize utxo selection through local variable caching of wallet data reused in computation --- .../sparrowwallet/drongo/wallet/Wallet.java | 22 +++++++++++-------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java index 504c6f2..11c3e08 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java @@ -1206,14 +1206,15 @@ public class Wallet extends Persistable implements Comparable { private List getGroupedUtxos(List utxoFilters, double feeRate, double longTermFeeRate, boolean groupByAddress, boolean includeSpentMempoolOutputs) { List outputGroups = new ArrayList<>(); Map walletTransactions = getWalletTransactions(); + Map walletTxos = getWalletTxos(); for(KeyPurpose keyPurpose : getWalletKeyPurposes()) { - getGroupedUtxos(outputGroups, getNode(keyPurpose), utxoFilters, walletTransactions, feeRate, longTermFeeRate, groupByAddress, includeSpentMempoolOutputs); + getGroupedUtxos(outputGroups, getNode(keyPurpose), utxoFilters, walletTransactions, walletTxos, feeRate, longTermFeeRate, groupByAddress, includeSpentMempoolOutputs); } for(Wallet childWallet : getChildWallets()) { if(childWallet.isNested()) { for(KeyPurpose keyPurpose : childWallet.getWalletKeyPurposes()) { - childWallet.getGroupedUtxos(outputGroups, childWallet.getNode(keyPurpose), utxoFilters, walletTransactions, feeRate, longTermFeeRate, groupByAddress, includeSpentMempoolOutputs); + childWallet.getGroupedUtxos(outputGroups, childWallet.getNode(keyPurpose), utxoFilters, walletTransactions, walletTxos, feeRate, longTermFeeRate, groupByAddress, includeSpentMempoolOutputs); } } } @@ -1221,7 +1222,8 @@ public class Wallet extends Persistable implements Comparable { return outputGroups; } - private void getGroupedUtxos(List outputGroups, WalletNode purposeNode, List utxoFilters, Map walletTransactions, double feeRate, double longTermFeeRate, boolean groupByAddress, boolean includeSpentMempoolOutputs) { + private void getGroupedUtxos(List outputGroups, WalletNode purposeNode, List utxoFilters, Map walletTransactions, Map walletTxos, double feeRate, double longTermFeeRate, boolean groupByAddress, boolean includeSpentMempoolOutputs) { + int inputWeightUnits = getInputWeightUnits(); for(WalletNode addressNode : purposeNode.getChildren()) { OutputGroup outputGroup = null; for(BlockTransactionHashIndex utxo : addressNode.getUnspentTransactionOutputs(includeSpentMempoolOutputs)) { @@ -1231,11 +1233,11 @@ public class Wallet extends Persistable implements Comparable { } if(outputGroup == null || !groupByAddress) { - outputGroup = new OutputGroup(addressNode.getWallet().getScriptType(), getStoredBlockHeight(), getInputWeightUnits(), feeRate, longTermFeeRate); + outputGroup = new OutputGroup(addressNode.getWallet().getScriptType(), getStoredBlockHeight(), inputWeightUnits, feeRate, longTermFeeRate); outputGroups.add(outputGroup); } - outputGroup.add(utxo, allInputsFromWallet(walletTransactions, utxo.getHash())); + outputGroup.add(utxo, allInputsFromWallet(walletTransactions, walletTxos, utxo.getHash())); } } } @@ -1248,10 +1250,11 @@ public class Wallet extends Persistable implements Comparable { */ public boolean allInputsFromWallet(Sha256Hash txId) { Map allTransactions = getWalletTransactions(); - return allInputsFromWallet(allTransactions, txId); + Map allTxos = getWalletTxos(); + return allInputsFromWallet(allTransactions, allTxos, txId); } - private boolean allInputsFromWallet(Map walletTransactions, Sha256Hash txId) { + private boolean allInputsFromWallet(Map walletTransactions, Map walletTxos, Sha256Hash txId) { BlockTransaction utxoBlkTx = walletTransactions.get(txId); if(utxoBlkTx == null) { //Provided txId was not a wallet transaction @@ -1269,7 +1272,7 @@ public class Wallet extends Persistable implements Comparable { TransactionOutput prevTxOut = prevBlkTx.getTransaction().getOutputs().get(index); BlockTransactionHashIndex spendingTXI = new BlockTransactionHashIndex(utxoBlkTx.getHash(), utxoBlkTx.getHeight(), utxoBlkTx.getDate(), utxoBlkTx.getFee(), i, prevTxOut.getValue()); BlockTransactionHashIndex spentTXO = new BlockTransactionHashIndex(prevBlkTx.getHash(), prevBlkTx.getHeight(), prevBlkTx.getDate(), prevBlkTx.getFee(), index, prevTxOut.getValue(), spendingTXI); - if(!isWalletTxo(spentTXO)) { + if(!walletTxos.containsKey(spentTXO)) { return false; } } @@ -1287,9 +1290,10 @@ public class Wallet extends Persistable implements Comparable { public long getMaxSpendable(List
    paymentAddresses, double feeRate, boolean includeSpentMempoolOutputs) { long maxInputValue = 0; + Map cachedInputWeightUnits = new HashMap<>(); Transaction transaction = new Transaction(); for(Map.Entry utxo : getWalletUtxos(includeSpentMempoolOutputs).entrySet()) { - int inputWeightUnits = utxo.getValue().getWallet().getInputWeightUnits(); + int inputWeightUnits = cachedInputWeightUnits.computeIfAbsent(utxo.getValue().getWallet(), Wallet::getInputWeightUnits); long minInputValue = (long)Math.ceil(feeRate * inputWeightUnits / WITNESS_SCALE_FACTOR); if(utxo.getKey().getValue() > minInputValue) { Transaction prevTx = getWalletTransaction(utxo.getKey().getHash()).getTransaction(); From cd1e21ebaa167823dc7e515f21b4acd640237025 Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Tue, 12 Jul 2022 10:43:20 +0200 Subject: [PATCH 127/155] prefer using libsecp256k1 to derive public keys from private --- .../java/com/sparrowwallet/drongo/crypto/ECKey.java | 10 ++++++++++ .../java/com/sparrowwallet/drongo/wallet/Wallet.java | 4 ++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/sparrowwallet/drongo/crypto/ECKey.java b/src/main/java/com/sparrowwallet/drongo/crypto/ECKey.java index be966e0..7f729fd 100644 --- a/src/main/java/com/sparrowwallet/drongo/crypto/ECKey.java +++ b/src/main/java/com/sparrowwallet/drongo/crypto/ECKey.java @@ -275,6 +275,16 @@ public class ECKey { * use {@code new BigInteger(1, bytes);} */ public static ECPoint publicPointFromPrivate(BigInteger privKey) { + if(Secp256k1Context.isEnabled()) { + try { + byte[] pubKeyBytes = NativeSecp256k1.computePubkey(Utils.bigIntegerToBytes(privKey, 32), false); + LazyECPoint lazyECPoint = new LazyECPoint(CURVE.getCurve(), pubKeyBytes); + return lazyECPoint.get(); + } catch(NativeSecp256k1Util.AssertFailException e) { + log.error("Error computing public key from private", e); + } + } + /* * TODO: FixedPointCombMultiplier currently doesn't support scalars longer than the group order, * but that could change in future versions. diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java index 11c3e08..d69755f 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java @@ -924,8 +924,8 @@ public class Wallet extends Persistable implements Comparable { * @return the number of weight units (WU) */ public int getInputWeightUnits() { - //Estimate assuming an input spending from a fresh receive node - it does not matter this node has no real utxos - WalletNode receiveNode = getFreshNode(KeyPurpose.RECEIVE); + //Estimate assuming an input spending from the parent receive node - it does not matter this node has no real utxos + WalletNode receiveNode = new WalletNode(this, KeyPurpose.RECEIVE); Transaction transaction = new Transaction(); TransactionOutput prevTxOut = transaction.addOutput(1L, receiveNode.getAddress()); From bd01cb87309bcc4a4739b63a6d7548ca1b25910e Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Thu, 14 Jul 2022 09:55:46 +0200 Subject: [PATCH 128/155] add method to warm the pubkey cache --- .../java/com/sparrowwallet/drongo/wallet/Wallet.java | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java index d69755f..a034dce 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java @@ -740,6 +740,17 @@ public class Wallet extends Persistable implements Comparable { } } + public void derivePublicKeys() { + for(KeyPurpose keyPurpose : KeyPurpose.DEFAULT_PURPOSES) { + WalletNode purposeNode = getNode(keyPurpose); + for(WalletNode addressNode : purposeNode.getChildren()) { + for(Keystore keystore : getKeystores()) { + keystore.getPubKey(addressNode); + } + } + } + } + public boolean isWalletTxo(TransactionInput txInput) { return getWalletTxos().keySet().stream().anyMatch(ref -> ref.getHash().equals(txInput.getOutpoint().getHash()) && ref.getIndex() == txInput.getOutpoint().getIndex()); } From 6d0d5b7f62781c15f16d4ce0b6e27d2298122d1e Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Thu, 14 Jul 2022 13:20:15 +0200 Subject: [PATCH 129/155] use an address node cache to avoid repeat wallet address lookups --- .../drongo/wallet/WalletTransaction.java | 36 +++++++++++++------ 1 file changed, 26 insertions(+), 10 deletions(-) diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/WalletTransaction.java b/src/main/java/com/sparrowwallet/drongo/wallet/WalletTransaction.java index 8248fdf..4910503 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/WalletTransaction.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/WalletTransaction.java @@ -1,6 +1,7 @@ package com.sparrowwallet.drongo.wallet; import com.sparrowwallet.drongo.address.Address; +import com.sparrowwallet.drongo.protocol.Script; import com.sparrowwallet.drongo.protocol.Sha256Hash; import com.sparrowwallet.drongo.protocol.Transaction; import com.sparrowwallet.drongo.psbt.PSBT; @@ -21,6 +22,8 @@ public class WalletTransaction { private final long fee; private final Map inputTransactions; + private Map> addressNodeMap = new HashMap<>(); + public WalletTransaction(Wallet wallet, Transaction transaction, List utxoSelectors, List> selectedUtxoSets, List payments, long fee) { this(wallet, transaction, utxoSelectors, selectedUtxoSets, payments, Collections.emptyMap(), fee); } @@ -139,24 +142,37 @@ public class WalletTransaction { } public boolean isWalletSend(Wallet wallet, Payment payment) { - if(payment.getAddress() != null && wallet != null) { - return wallet.isWalletOutputScript(payment.getAddress().getOutputScript()); + if(wallet == null) { + return false; } - return false; + return getAddressNodeMap(wallet).get(payment.getAddress()) != null; } - public List getConsolidationSendNodes() { - List walletNodes = new ArrayList<>(); + public void updateAddressNodeMap(Map> addressNodeMap, Wallet wallet) { + this.addressNodeMap = addressNodeMap; + getAddressNodeMap(wallet); + } + + public Map getAddressNodeMap(Wallet wallet) { + Map walletOutputScripts = null; + + Map walletAddressNodeMap = addressNodeMap.computeIfAbsent(wallet, w -> new LinkedHashMap<>()); for(Payment payment : payments) { - if(payment.getAddress() != null && getWallet() != null) { - WalletNode walletNode = getWallet().getWalletOutputScripts().get(payment.getAddress().getOutputScript()); - if(walletNode != null) { - walletNodes.add(walletNode); + if(walletAddressNodeMap.containsKey(payment.getAddress())) { + continue; + } + + if(payment.getAddress() != null && wallet != null) { + if(walletOutputScripts == null) { + walletOutputScripts = wallet.getWalletOutputScripts(); } + + WalletNode walletNode = walletOutputScripts.get(payment.getAddress().getOutputScript()); + walletAddressNodeMap.put(payment.getAddress(), walletNode); } } - return walletNodes; + return walletAddressNodeMap; } } From 377843a4a5a3b00fc6267e8aaeeff86e6899ce46 Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Thu, 14 Jul 2022 14:48:05 +0200 Subject: [PATCH 130/155] add performance optimization when requesting purpose node for deep wallets --- .../sparrowwallet/drongo/wallet/WalletNode.java | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/WalletNode.java b/src/main/java/com/sparrowwallet/drongo/wallet/WalletNode.java index 538dd58..c2676ea 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/WalletNode.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/WalletNode.java @@ -205,6 +205,20 @@ public class WalletNode extends Persistable implements Comparable { } public synchronized Set fillToIndex(int index) { + //Optimization to check if child nodes already monotonically increment to the desired index + int indexCheck = 0; + for(WalletNode childNode : getChildren()) { + if(childNode.index == indexCheck) { + indexCheck++; + } else { + break; + } + + if(childNode.index == index) { + return Collections.emptySet(); + } + } + Set newNodes = new TreeSet<>(); for(int i = 0; i <= index; i++) { WalletNode node = new WalletNode(wallet, getKeyPurpose(), i); From c4d2041a770a3f880d09ea0e5e7aa721d340df39 Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Thu, 14 Jul 2022 15:08:01 +0200 Subject: [PATCH 131/155] optimize retrieving unspent utxos --- .../java/com/sparrowwallet/drongo/wallet/WalletNode.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/WalletNode.java b/src/main/java/com/sparrowwallet/drongo/wallet/WalletNode.java index c2676ea..269e99e 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/WalletNode.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/WalletNode.java @@ -166,8 +166,13 @@ public class WalletNode extends Persistable implements Comparable { } public Set getUnspentTransactionOutputs(boolean includeSpentMempoolOutputs) { + if(transactionOutputs.isEmpty()) { + return Collections.emptySet(); + } + Set unspentTXOs = new TreeSet<>(transactionOutputs); - return unspentTXOs.stream().filter(txo -> !txo.isSpent() || (includeSpentMempoolOutputs && txo.getSpentBy().getHeight() <= 0)).collect(Collectors.toCollection(HashSet::new)); + unspentTXOs.removeIf(txo -> txo.isSpent() && (!includeSpentMempoolOutputs || txo.getSpentBy().getHeight() > 0)); + return unspentTXOs; } public long getUnspentValue() { From 67bc479ae9369f5908446210c40996b584cdd4a2 Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Thu, 14 Jul 2022 15:30:39 +0200 Subject: [PATCH 132/155] prevent concurrent modification exception while copying node tree --- src/main/java/com/sparrowwallet/drongo/wallet/WalletNode.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/WalletNode.java b/src/main/java/com/sparrowwallet/drongo/wallet/WalletNode.java index 269e99e..5e2b502 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/WalletNode.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/WalletNode.java @@ -325,7 +325,7 @@ public class WalletNode extends Persistable implements Comparable { copy.setId(getId()); copy.setLabel(label); - for(WalletNode child : getChildren()) { + for(WalletNode child : new ArrayList<>(getChildren())) { copy.children.add(child.copy(walletCopy)); } From d489aa6af9e22e9b707570d9c19ab10aec0d0a28 Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Thu, 14 Jul 2022 15:37:48 +0200 Subject: [PATCH 133/155] follow up --- src/main/java/com/sparrowwallet/drongo/wallet/WalletNode.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/WalletNode.java b/src/main/java/com/sparrowwallet/drongo/wallet/WalletNode.java index 5e2b502..269e99e 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/WalletNode.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/WalletNode.java @@ -325,7 +325,7 @@ public class WalletNode extends Persistable implements Comparable { copy.setId(getId()); copy.setLabel(label); - for(WalletNode child : new ArrayList<>(getChildren())) { + for(WalletNode child : getChildren()) { copy.children.add(child.copy(walletCopy)); } From fefebbabb5202330de028abe05344a91cf602018 Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Thu, 14 Jul 2022 16:07:55 +0200 Subject: [PATCH 134/155] remove key derivation method --- .../java/com/sparrowwallet/drongo/wallet/Wallet.java | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java index a034dce..d69755f 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java @@ -740,17 +740,6 @@ public class Wallet extends Persistable implements Comparable { } } - public void derivePublicKeys() { - for(KeyPurpose keyPurpose : KeyPurpose.DEFAULT_PURPOSES) { - WalletNode purposeNode = getNode(keyPurpose); - for(WalletNode addressNode : purposeNode.getChildren()) { - for(Keystore keystore : getKeystores()) { - keystore.getPubKey(addressNode); - } - } - } - } - public boolean isWalletTxo(TransactionInput txInput) { return getWalletTxos().keySet().stream().anyMatch(ref -> ref.getHash().equals(txInput.getOutpoint().getHash()) && ref.getIndex() == txInput.getOutpoint().getIndex()); } From 9ae1f68dc42529085edcc8c10d9bcfdbf9639448 Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Fri, 15 Jul 2022 13:42:27 +0200 Subject: [PATCH 135/155] address and related optimizations --- .../sparrowwallet/drongo/address/Address.java | 19 +++++++++---------- .../drongo/address/P2PKAddress.java | 14 ++++++++------ .../drongo/address/P2PKHAddress.java | 4 ++-- .../drongo/address/P2SHAddress.java | 4 ++-- .../drongo/address/P2TRAddress.java | 12 ++++-------- .../drongo/address/P2WPKHAddress.java | 6 +++--- .../drongo/address/P2WSHAddress.java | 6 +++--- .../sparrowwallet/drongo/crypto/ECKey.java | 11 ++++------- .../com/sparrowwallet/drongo/psbt/PSBT.java | 6 +++--- .../drongo/wallet/WalletTransaction.java | 12 ++++++++---- .../drongo/address/AddressTest.java | 4 ++-- 11 files changed, 48 insertions(+), 50 deletions(-) diff --git a/src/main/java/com/sparrowwallet/drongo/address/Address.java b/src/main/java/com/sparrowwallet/drongo/address/Address.java index e557ada..f13663c 100644 --- a/src/main/java/com/sparrowwallet/drongo/address/Address.java +++ b/src/main/java/com/sparrowwallet/drongo/address/Address.java @@ -9,14 +9,14 @@ import com.sparrowwallet.drongo.protocol.ScriptType; import java.util.Arrays; public abstract class Address { - protected final byte[] hash; + protected final byte[] data; - public Address(byte[] hash) { - this.hash = hash; + public Address(byte[] data) { + this.data = data; } - public byte[] getHash() { - return hash; + public byte[] getData() { + return data; } public String getAddress() { @@ -24,7 +24,7 @@ public abstract class Address { } public String getAddress(Network network) { - return Base58.encodeChecked(getVersion(network), hash); + return Base58.encodeChecked(getVersion(network), data); } public String toString() { @@ -50,16 +50,15 @@ public abstract class Address { public abstract String getOutputScriptDataType(); public boolean equals(Object obj) { - if(!(obj instanceof Address)) { + if(!(obj instanceof Address address)) { return false; } - Address address = (Address)obj; - return address.getAddress().equals(this.getAddress()); + return Arrays.equals(data, address.data) && getVersion(Network.get()) == address.getVersion(Network.get()); } public int hashCode() { - return getAddress().hashCode(); + return Arrays.hashCode(data) + getVersion(Network.get()); } public static Address fromString(String address) throws InvalidAddressException { diff --git a/src/main/java/com/sparrowwallet/drongo/address/P2PKAddress.java b/src/main/java/com/sparrowwallet/drongo/address/P2PKAddress.java index aaa956b..0680b75 100644 --- a/src/main/java/com/sparrowwallet/drongo/address/P2PKAddress.java +++ b/src/main/java/com/sparrowwallet/drongo/address/P2PKAddress.java @@ -6,11 +6,8 @@ import com.sparrowwallet.drongo.protocol.Script; import com.sparrowwallet.drongo.protocol.ScriptType; public class P2PKAddress extends Address { - private final byte[] pubKey; - public P2PKAddress(byte[] pubKey) { - super(Utils.sha256hash160(pubKey)); - this.pubKey = pubKey; + super(pubKey); } @Override @@ -18,17 +15,22 @@ public class P2PKAddress extends Address { return network.getP2PKHAddressHeader(); } + @Override + public String getAddress(Network network) { + return Utils.bytesToHex(data); + } + public ScriptType getScriptType() { return ScriptType.P2PK; } public Script getOutputScript() { - return getScriptType().getOutputScript(pubKey); + return getScriptType().getOutputScript(data); } @Override public byte[] getOutputScriptData() { - return pubKey; + return data; } @Override diff --git a/src/main/java/com/sparrowwallet/drongo/address/P2PKHAddress.java b/src/main/java/com/sparrowwallet/drongo/address/P2PKHAddress.java index dcf9488..e1d6792 100644 --- a/src/main/java/com/sparrowwallet/drongo/address/P2PKHAddress.java +++ b/src/main/java/com/sparrowwallet/drongo/address/P2PKHAddress.java @@ -21,12 +21,12 @@ public class P2PKHAddress extends Address { @Override public Script getOutputScript() { - return getScriptType().getOutputScript(hash); + return getScriptType().getOutputScript(data); } @Override public byte[] getOutputScriptData() { - return hash; + return data; } @Override diff --git a/src/main/java/com/sparrowwallet/drongo/address/P2SHAddress.java b/src/main/java/com/sparrowwallet/drongo/address/P2SHAddress.java index 8692a07..99687d5 100644 --- a/src/main/java/com/sparrowwallet/drongo/address/P2SHAddress.java +++ b/src/main/java/com/sparrowwallet/drongo/address/P2SHAddress.java @@ -22,12 +22,12 @@ public class P2SHAddress extends Address { @Override public Script getOutputScript() { - return getScriptType().getOutputScript(hash); + return getScriptType().getOutputScript(data); } @Override public byte[] getOutputScriptData() { - return hash; + return data; } @Override diff --git a/src/main/java/com/sparrowwallet/drongo/address/P2TRAddress.java b/src/main/java/com/sparrowwallet/drongo/address/P2TRAddress.java index a263762..eb668a9 100644 --- a/src/main/java/com/sparrowwallet/drongo/address/P2TRAddress.java +++ b/src/main/java/com/sparrowwallet/drongo/address/P2TRAddress.java @@ -1,17 +1,13 @@ package com.sparrowwallet.drongo.address; import com.sparrowwallet.drongo.Network; -import com.sparrowwallet.drongo.Utils; import com.sparrowwallet.drongo.protocol.Bech32; import com.sparrowwallet.drongo.protocol.Script; import com.sparrowwallet.drongo.protocol.ScriptType; public class P2TRAddress extends Address { - private final byte[] pubKey; - public P2TRAddress(byte[] pubKey) { - super(Utils.sha256hash160(pubKey)); - this.pubKey = pubKey; + super(pubKey); } @Override @@ -21,7 +17,7 @@ public class P2TRAddress extends Address { @Override public String getAddress(Network network) { - return Bech32.encode(network.getBech32AddressHRP(), getVersion(), pubKey); + return Bech32.encode(network.getBech32AddressHRP(), getVersion(), data); } @Override @@ -31,12 +27,12 @@ public class P2TRAddress extends Address { @Override public Script getOutputScript() { - return getScriptType().getOutputScript(pubKey); + return getScriptType().getOutputScript(data); } @Override public byte[] getOutputScriptData() { - return pubKey; + return data; } @Override diff --git a/src/main/java/com/sparrowwallet/drongo/address/P2WPKHAddress.java b/src/main/java/com/sparrowwallet/drongo/address/P2WPKHAddress.java index b4ed379..3db918a 100644 --- a/src/main/java/com/sparrowwallet/drongo/address/P2WPKHAddress.java +++ b/src/main/java/com/sparrowwallet/drongo/address/P2WPKHAddress.java @@ -17,7 +17,7 @@ public class P2WPKHAddress extends Address { @Override public String getAddress(Network network) { - return Bech32.encode(network.getBech32AddressHRP(), getVersion(), hash); + return Bech32.encode(network.getBech32AddressHRP(), getVersion(), data); } @Override @@ -27,12 +27,12 @@ public class P2WPKHAddress extends Address { @Override public Script getOutputScript() { - return getScriptType().getOutputScript(hash); + return getScriptType().getOutputScript(data); } @Override public byte[] getOutputScriptData() { - return hash; + return data; } @Override diff --git a/src/main/java/com/sparrowwallet/drongo/address/P2WSHAddress.java b/src/main/java/com/sparrowwallet/drongo/address/P2WSHAddress.java index 0886dc4..6ebd886 100644 --- a/src/main/java/com/sparrowwallet/drongo/address/P2WSHAddress.java +++ b/src/main/java/com/sparrowwallet/drongo/address/P2WSHAddress.java @@ -15,7 +15,7 @@ public class P2WSHAddress extends Address { @Override public String getAddress(Network network) { - return Bech32.encode(network.getBech32AddressHRP(), getVersion(), hash); + return Bech32.encode(network.getBech32AddressHRP(), getVersion(), data); } @Override @@ -25,12 +25,12 @@ public class P2WSHAddress extends Address { @Override public Script getOutputScript() { - return getScriptType().getOutputScript(hash); + return getScriptType().getOutputScript(data); } @Override public byte[] getOutputScriptData() { - return hash; + return data; } @Override diff --git a/src/main/java/com/sparrowwallet/drongo/crypto/ECKey.java b/src/main/java/com/sparrowwallet/drongo/crypto/ECKey.java index 7f729fd..6fa2e92 100644 --- a/src/main/java/com/sparrowwallet/drongo/crypto/ECKey.java +++ b/src/main/java/com/sparrowwallet/drongo/crypto/ECKey.java @@ -275,6 +275,10 @@ public class ECKey { * use {@code new BigInteger(1, bytes);} */ public static ECPoint publicPointFromPrivate(BigInteger privKey) { + if (privKey.bitLength() > CURVE.getN().bitLength()) { + privKey = privKey.mod(CURVE.getN()); + } + if(Secp256k1Context.isEnabled()) { try { byte[] pubKeyBytes = NativeSecp256k1.computePubkey(Utils.bigIntegerToBytes(privKey, 32), false); @@ -285,13 +289,6 @@ public class ECKey { } } - /* - * TODO: FixedPointCombMultiplier currently doesn't support scalars longer than the group order, - * but that could change in future versions. - */ - if (privKey.bitLength() > CURVE.getN().bitLength()) { - privKey = privKey.mod(CURVE.getN()); - } return new FixedPointCombMultiplier().multiply(CURVE.getG(), privKey); } diff --git a/src/main/java/com/sparrowwallet/drongo/psbt/PSBT.java b/src/main/java/com/sparrowwallet/drongo/psbt/PSBT.java index 6968115..a16ed47 100644 --- a/src/main/java/com/sparrowwallet/drongo/psbt/PSBT.java +++ b/src/main/java/com/sparrowwallet/drongo/psbt/PSBT.java @@ -134,10 +134,10 @@ public class PSBT { for(TransactionOutput txOutput : transaction.getOutputs()) { try { Address address = txOutput.getScript().getToAddresses()[0]; - if(walletTransaction.getPayments().stream().anyMatch(payment -> payment.getAddress().equals(address))) { - outputNodes.add(wallet.getWalletAddresses().getOrDefault(address, null)); + if(walletTransaction.getAddressNodeMap().containsKey(address)) { + outputNodes.add(walletTransaction.getAddressNodeMap().get(address)); } else if(walletTransaction.getChangeMap().keySet().stream().anyMatch(changeNode -> changeNode.getAddress().equals(address))) { - outputNodes.add(wallet.getWalletAddresses().getOrDefault(address, null)); + outputNodes.add(walletTransaction.getChangeMap().keySet().stream().filter(changeNode -> changeNode.getAddress().equals(address)).findFirst().orElse(null)); } } catch(NonStandardScriptException e) { //Ignore, likely OP_RETURN output diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/WalletTransaction.java b/src/main/java/com/sparrowwallet/drongo/wallet/WalletTransaction.java index 4910503..546eede 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/WalletTransaction.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/WalletTransaction.java @@ -154,8 +154,12 @@ public class WalletTransaction { getAddressNodeMap(wallet); } + public Map getAddressNodeMap() { + return getAddressNodeMap(getWallet()); + } + public Map getAddressNodeMap(Wallet wallet) { - Map walletOutputScripts = null; + Map walletAddresses = null; Map walletAddressNodeMap = addressNodeMap.computeIfAbsent(wallet, w -> new LinkedHashMap<>()); for(Payment payment : payments) { @@ -164,11 +168,11 @@ public class WalletTransaction { } if(payment.getAddress() != null && wallet != null) { - if(walletOutputScripts == null) { - walletOutputScripts = wallet.getWalletOutputScripts(); + if(walletAddresses == null) { + walletAddresses = wallet.getWalletAddresses(); } - WalletNode walletNode = walletOutputScripts.get(payment.getAddress().getOutputScript()); + WalletNode walletNode = walletAddresses.get(payment.getAddress()); walletAddressNodeMap.put(payment.getAddress(), walletNode); } } diff --git a/src/test/java/com/sparrowwallet/drongo/address/AddressTest.java b/src/test/java/com/sparrowwallet/drongo/address/AddressTest.java index fd4b799..745f33b 100644 --- a/src/test/java/com/sparrowwallet/drongo/address/AddressTest.java +++ b/src/test/java/com/sparrowwallet/drongo/address/AddressTest.java @@ -98,7 +98,7 @@ public class AddressTest { Address address = (i % 2 == 0 ? new P2PKHAddress(values) : new P2WPKHAddress(values)); String strAddress = address.toString(); Address checkAddress = Address.fromString(strAddress); - Assert.assertArrayEquals(values, checkAddress.getHash()); + Assert.assertArrayEquals(values, checkAddress.getData()); } byte[] values32 = new byte[32]; @@ -107,7 +107,7 @@ public class AddressTest { Address address = new P2WSHAddress(values32); String strAddress = address.toString(); Address checkAddress = Address.fromString(strAddress); - Assert.assertArrayEquals(values32, checkAddress.getHash()); + Assert.assertArrayEquals(values32, checkAddress.getData()); } } From 5de3abd36230d545f11bad3b25a21d23ffbbe9cd Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Mon, 18 Jul 2022 16:11:59 +0200 Subject: [PATCH 136/155] store address data on wallet nodes --- .../sparrowwallet/drongo/address/Address.java | 8 +++++-- .../drongo/address/P2PKAddress.java | 9 -------- .../drongo/address/P2PKHAddress.java | 10 --------- .../drongo/address/P2SHAddress.java | 10 --------- .../drongo/address/P2TRAddress.java | 10 --------- .../drongo/address/P2WPKHAddress.java | 10 --------- .../drongo/address/P2WSHAddress.java | 10 --------- .../sparrowwallet/drongo/wallet/Keystore.java | 17 +++++++++++++-- .../drongo/wallet/WalletNode.java | 21 ++++++++++++++++++- 9 files changed, 41 insertions(+), 64 deletions(-) diff --git a/src/main/java/com/sparrowwallet/drongo/address/Address.java b/src/main/java/com/sparrowwallet/drongo/address/Address.java index f13663c..af55c62 100644 --- a/src/main/java/com/sparrowwallet/drongo/address/Address.java +++ b/src/main/java/com/sparrowwallet/drongo/address/Address.java @@ -43,9 +43,13 @@ public abstract class Address { public abstract ScriptType getScriptType(); - public abstract Script getOutputScript(); + public Script getOutputScript() { + return getScriptType().getOutputScript(data); + } - public abstract byte[] getOutputScriptData(); + public byte[] getOutputScriptData() { + return data; + } public abstract String getOutputScriptDataType(); diff --git a/src/main/java/com/sparrowwallet/drongo/address/P2PKAddress.java b/src/main/java/com/sparrowwallet/drongo/address/P2PKAddress.java index 0680b75..dd2e1da 100644 --- a/src/main/java/com/sparrowwallet/drongo/address/P2PKAddress.java +++ b/src/main/java/com/sparrowwallet/drongo/address/P2PKAddress.java @@ -24,15 +24,6 @@ public class P2PKAddress extends Address { return ScriptType.P2PK; } - public Script getOutputScript() { - return getScriptType().getOutputScript(data); - } - - @Override - public byte[] getOutputScriptData() { - return data; - } - @Override public String getOutputScriptDataType() { return "Public Key"; diff --git a/src/main/java/com/sparrowwallet/drongo/address/P2PKHAddress.java b/src/main/java/com/sparrowwallet/drongo/address/P2PKHAddress.java index e1d6792..6de9b9a 100644 --- a/src/main/java/com/sparrowwallet/drongo/address/P2PKHAddress.java +++ b/src/main/java/com/sparrowwallet/drongo/address/P2PKHAddress.java @@ -19,16 +19,6 @@ public class P2PKHAddress extends Address { return ScriptType.P2PKH; } - @Override - public Script getOutputScript() { - return getScriptType().getOutputScript(data); - } - - @Override - public byte[] getOutputScriptData() { - return data; - } - @Override public String getOutputScriptDataType() { return "Public Key Hash"; diff --git a/src/main/java/com/sparrowwallet/drongo/address/P2SHAddress.java b/src/main/java/com/sparrowwallet/drongo/address/P2SHAddress.java index 99687d5..de02e8f 100644 --- a/src/main/java/com/sparrowwallet/drongo/address/P2SHAddress.java +++ b/src/main/java/com/sparrowwallet/drongo/address/P2SHAddress.java @@ -20,16 +20,6 @@ public class P2SHAddress extends Address { return ScriptType.P2SH; } - @Override - public Script getOutputScript() { - return getScriptType().getOutputScript(data); - } - - @Override - public byte[] getOutputScriptData() { - return data; - } - @Override public String getOutputScriptDataType() { return "Script Hash"; diff --git a/src/main/java/com/sparrowwallet/drongo/address/P2TRAddress.java b/src/main/java/com/sparrowwallet/drongo/address/P2TRAddress.java index eb668a9..255982a 100644 --- a/src/main/java/com/sparrowwallet/drongo/address/P2TRAddress.java +++ b/src/main/java/com/sparrowwallet/drongo/address/P2TRAddress.java @@ -25,16 +25,6 @@ public class P2TRAddress extends Address { return ScriptType.P2TR; } - @Override - public Script getOutputScript() { - return getScriptType().getOutputScript(data); - } - - @Override - public byte[] getOutputScriptData() { - return data; - } - @Override public String getOutputScriptDataType() { return "Taproot"; diff --git a/src/main/java/com/sparrowwallet/drongo/address/P2WPKHAddress.java b/src/main/java/com/sparrowwallet/drongo/address/P2WPKHAddress.java index 3db918a..f6358bb 100644 --- a/src/main/java/com/sparrowwallet/drongo/address/P2WPKHAddress.java +++ b/src/main/java/com/sparrowwallet/drongo/address/P2WPKHAddress.java @@ -25,16 +25,6 @@ public class P2WPKHAddress extends Address { return ScriptType.P2WPKH; } - @Override - public Script getOutputScript() { - return getScriptType().getOutputScript(data); - } - - @Override - public byte[] getOutputScriptData() { - return data; - } - @Override public String getOutputScriptDataType() { return "Witness Public Key Hash"; diff --git a/src/main/java/com/sparrowwallet/drongo/address/P2WSHAddress.java b/src/main/java/com/sparrowwallet/drongo/address/P2WSHAddress.java index 6ebd886..3b70585 100644 --- a/src/main/java/com/sparrowwallet/drongo/address/P2WSHAddress.java +++ b/src/main/java/com/sparrowwallet/drongo/address/P2WSHAddress.java @@ -23,16 +23,6 @@ public class P2WSHAddress extends Address { return ScriptType.P2WSH; } - @Override - public Script getOutputScript() { - return getScriptType().getOutputScript(data); - } - - @Override - public byte[] getOutputScriptData() { - return data; - } - @Override public String getOutputScriptDataType() { return "Witness Script Hash"; diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/Keystore.java b/src/main/java/com/sparrowwallet/drongo/wallet/Keystore.java index b4079e5..6045866 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/Keystore.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/Keystore.java @@ -31,7 +31,10 @@ public class Keystore extends Persistable { private DeterministicSeed seed; //For BIP47 keystores - not persisted but must be unencrypted to generate keys - private ExtendedKey bip47ExtendedPrivateKey; + private transient ExtendedKey bip47ExtendedPrivateKey; + + //Avoid performing repeated expensive seed derivation checks + private transient boolean extendedPublicKeyChecked; public Keystore() { this(DEFAULT_LABEL); @@ -83,6 +86,7 @@ public class Keystore extends Persistable { public void setExtendedPublicKey(ExtendedKey extendedPublicKey) { this.extendedPublicKey = extendedPublicKey; + this.extendedPublicKeyChecked = false; } public PaymentCode getExternalPaymentCode() { @@ -125,6 +129,14 @@ public class Keystore extends Persistable { return hasMasterPrivateKey() || (source == KeystoreSource.SW_PAYMENT_CODE && bip47ExtendedPrivateKey != null); } + public boolean needsPassphrase() { + if(seed != null) { + return seed.needsPassphrase(); + } + + return false; + } + public PaymentCode getPaymentCode() { DeterministicKey bip47Key = bip47ExtendedPrivateKey.getKey(); return new PaymentCode(bip47Key.getPubKey(), bip47Key.getChainCode()); @@ -278,7 +290,7 @@ public class Keystore extends Persistable { throw new InvalidKeystoreException("Source of " + source + " but no seed or master private key is present"); } - if((seed != null && !seed.isEncrypted()) || (masterPrivateExtendedKey != null && !masterPrivateExtendedKey.isEncrypted())) { + if(!extendedPublicKeyChecked && ((seed != null && !seed.isEncrypted()) || (masterPrivateExtendedKey != null && !masterPrivateExtendedKey.isEncrypted()))) { try { List derivation = getKeyDerivation().getDerivation(); DeterministicKey derivedKey = getExtendedMasterPrivateKey().getKey(derivation); @@ -287,6 +299,7 @@ public class Keystore extends Persistable { if(!xpub.equals(getExtendedPublicKey())) { throw new InvalidKeystoreException("Specified extended public key does not match public key derived from seed"); } + extendedPublicKeyChecked = true; } catch(MnemonicException e) { throw new InvalidKeystoreException("Invalid mnemonic specified for seed", e); } diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/WalletNode.java b/src/main/java/com/sparrowwallet/drongo/wallet/WalletNode.java index 269e99e..d4267c2 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/WalletNode.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/WalletNode.java @@ -13,6 +13,7 @@ import java.util.stream.Collectors; public class WalletNode extends Persistable implements Comparable { private final String derivationPath; private String label; + private Address address; private TreeSet children = new TreeSet<>(); private TreeSet transactionOutputs = new TreeSet<>(); @@ -267,11 +268,28 @@ public class WalletNode extends Persistable implements Comparable { } public Address getAddress() { + if(address != null) { + return address; + } + + if(wallet.getKeystores().stream().noneMatch(Keystore::needsPassphrase)) { + address = wallet.getAddress(this); + return address; + } + return wallet.getAddress(this); } + public byte[] getAddressData() { + return address == null ? null : address.getData(); + } + + public void setAddress(Address address) { + this.address = address; + } + public Script getOutputScript() { - return wallet.getOutputScript(this); + return getAddress().getOutputScript(); } public String getOutputDescriptor() { @@ -324,6 +342,7 @@ public class WalletNode extends Persistable implements Comparable { WalletNode copy = new WalletNode(walletCopy, derivationPath); copy.setId(getId()); copy.setLabel(label); + copy.setAddress(address); for(WalletNode child : getChildren()) { copy.children.add(child.copy(walletCopy)); From f10688279a7a761c734c80c051237c0a4a90928b Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Tue, 19 Jul 2022 13:21:21 +0200 Subject: [PATCH 137/155] add bip38 decryption functionality and tests --- .../java/com/sparrowwallet/drongo/Utils.java | 7 + .../sparrowwallet/drongo/crypto/BIP38.java | 165 ++++++++++++++++++ .../drongo/crypto/BIP38Test.java | 33 ++++ 3 files changed, 205 insertions(+) create mode 100644 src/main/java/com/sparrowwallet/drongo/crypto/BIP38.java create mode 100644 src/test/java/com/sparrowwallet/drongo/crypto/BIP38Test.java diff --git a/src/main/java/com/sparrowwallet/drongo/Utils.java b/src/main/java/com/sparrowwallet/drongo/Utils.java index f749d19..34f8d5b 100644 --- a/src/main/java/com/sparrowwallet/drongo/Utils.java +++ b/src/main/java/com/sparrowwallet/drongo/Utils.java @@ -121,6 +121,13 @@ public class Utils { } } + public static byte[] concat(byte[] a, byte[] b) { + byte[] c = new byte[a.length + b.length]; + System.arraycopy(a, 0, c, 0, a.length); + System.arraycopy(b, 0, c, a.length, b.length); + return c; + } + /** Parse 4 bytes from the byte array (starting at the offset) as unsigned 32-bit integer in little endian format. */ public static long readUint32(byte[] bytes, int offset) { return (bytes[offset] & 0xffl) | diff --git a/src/main/java/com/sparrowwallet/drongo/crypto/BIP38.java b/src/main/java/com/sparrowwallet/drongo/crypto/BIP38.java new file mode 100644 index 0000000..c51e751 --- /dev/null +++ b/src/main/java/com/sparrowwallet/drongo/crypto/BIP38.java @@ -0,0 +1,165 @@ +/** + * Implementation of BIP38 encryption / decryption / key-address generation + * Based on https://github.com/bitcoin/bips/blob/master/bip-0038.mediawiki + * + * Tips much appreciated: 1EmwBbfgH7BPMoCpcFzyzgAN9Ya7jm8L1Z :) + * + * Copyright 2014 Diego Basch + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.sparrowwallet.drongo.crypto; + +import com.sparrowwallet.drongo.Drongo; +import com.sparrowwallet.drongo.Utils; +import com.sparrowwallet.drongo.protocol.Base58; +import com.sparrowwallet.drongo.protocol.Sha256Hash; +import org.bouncycastle.crypto.generators.SCrypt; +import org.bouncycastle.math.ec.ECPoint; + +import javax.crypto.Cipher; +import javax.crypto.spec.SecretKeySpec; +import java.io.UnsupportedEncodingException; +import java.math.BigInteger; +import java.security.GeneralSecurityException; +import java.util.Arrays; + +import static com.sparrowwallet.drongo.crypto.ECKey.CURVE; + +public class BIP38 { + /** + * Decrypts an encrypted key. + * @param passphrase + * @param encryptedKey + * @throws UnsupportedEncodingException + * @throws GeneralSecurityException + */ + public static DumpedPrivateKey decrypt(String passphrase, String encryptedKey) throws UnsupportedEncodingException, GeneralSecurityException { + byte[] encryptedKeyBytes = Base58.decodeChecked(encryptedKey); + DumpedPrivateKey result; + byte ec = encryptedKeyBytes[1]; + switch (ec) { + case 0x43: result = decryptEC(passphrase, encryptedKeyBytes); + break; + case 0x42: result = decryptNoEC(passphrase, encryptedKeyBytes); + break; + default: throw new RuntimeException("Invalid key - second byte is: " + ec); + } + return result; + } + + /** + * Decrypts a key encrypted with EC multiplication + * @param passphrase + * @param encryptedKey + * @throws UnsupportedEncodingException + * @throws GeneralSecurityException + */ + public static DumpedPrivateKey decryptEC(String passphrase, byte[] encryptedKey) throws UnsupportedEncodingException, GeneralSecurityException { + + byte flagByte = encryptedKey[2]; + byte[] passFactor; + boolean hasLot = (flagByte & 4) == 4; + byte[] ownerSalt = Arrays.copyOfRange(encryptedKey, 7, 15 - (flagByte & 4)); + if (!hasLot) { + passFactor = SCrypt.generate(passphrase.getBytes("UTF8"), ownerSalt, 16384, 8, 8, 32); + } + else { + byte[] preFactor = SCrypt.generate(passphrase.getBytes("UTF8"), ownerSalt, 16384, 8, 8, 32); + byte[] ownerEntropy = Arrays.copyOfRange(encryptedKey, 7, 15); + byte[] tmp = Utils.concat(preFactor, ownerEntropy); + passFactor = Sha256Hash.hashTwice(tmp, 0, 40); + } + + byte[] addressHash = Arrays.copyOfRange(encryptedKey, 3, 7); + ECPoint g = CURVE.getG(); + ECPoint p = g.multiply(new BigInteger(1, passFactor)); + byte[] passPoint = p.getEncoded(true); + byte[] salt = new byte[12]; + byte[] encryptedPart2 = Arrays.copyOfRange(encryptedKey, 23, 39); + System.arraycopy(addressHash, 0, salt, 0, 4); + System.arraycopy(encryptedKey, 7, salt, 4, 8); + + byte[] secondKey = SCrypt.generate(passPoint, salt, 1024, 1, 1, 64); + byte[] derivedHalf1 = Arrays.copyOfRange(secondKey, 0, 32); + byte[] derivedHalf2 = Arrays.copyOfRange(secondKey, 32, 64); + byte[] m2 = decryptAES(encryptedPart2, derivedHalf2); + + byte[] encryptedPart1 = new byte[16]; + System.arraycopy(encryptedKey, 15, encryptedPart1, 0, 8); + + byte[] seedB = new byte[24]; + + for (int i = 0; i < 16; i++) { + m2[i] = (byte) (m2[i] ^ derivedHalf1[16 + i]); + } + System.arraycopy(m2, 0, encryptedPart1, 8, 8); + + byte[] m1 = decryptAES(encryptedPart1, derivedHalf2); + + for (int i = 0; i < 16; i++) { + seedB[i] = (byte) (m1[i] ^ derivedHalf1[i]); + } + + System.arraycopy(m2, 8, seedB, 16, 8); + byte[] factorB = Sha256Hash.hashTwice(seedB, 0, 24); + BigInteger n = CURVE.getN(); + BigInteger pk = new BigInteger(1, passFactor).multiply(new BigInteger(1, factorB)).remainder(n); + + ECKey privKey = ECKey.fromPrivate(pk, false); + return privKey.getPrivateKeyEncoded(); + } + + /** + * Decrypts a key that was encrypted without EC multiplication. + * @param passphrase + * @param encryptedKey + * @throws UnsupportedEncodingException + * @throws GeneralSecurityException + */ + public static DumpedPrivateKey decryptNoEC(String passphrase, byte[] encryptedKey) throws UnsupportedEncodingException, GeneralSecurityException { + + byte[] addressHash = Arrays.copyOfRange(encryptedKey, 3, 7); + byte[] scryptKey = SCrypt.generate(passphrase.getBytes("UTF8"), addressHash, 16384, 8, 8, 64); + byte[] derivedHalf1 = Arrays.copyOfRange(scryptKey, 0, 32); + byte[] derivedHalf2 = Arrays.copyOfRange(scryptKey, 32, 64); + + byte[] encryptedHalf1 = Arrays.copyOfRange(encryptedKey, 7, 23); + byte[] encryptedHalf2 = Arrays.copyOfRange(encryptedKey, 23, 39); + byte[] k1 = decryptAES(encryptedHalf1, derivedHalf2); + byte[] k2 = decryptAES(encryptedHalf2, derivedHalf2); + byte[] keyBytes = new byte[32]; + for (int i = 0; i < 16; i++) { + keyBytes[i] = (byte) (k1[i] ^ derivedHalf1[i]); + keyBytes[i + 16] = (byte) (k2[i] ^ derivedHalf1[i + 16]); + } + + boolean compressed = (encryptedKey[2] & (byte) 0x20) == 0x20; + ECKey k = new ECKey(new BigInteger(1, keyBytes), null, compressed); + return k.getPrivateKeyEncoded(); + } + + /** + * Decrypts ciphertext with AES + * @param ciphertext + * @param key + * @throws GeneralSecurityException + */ + public static byte[] decryptAES(byte[] ciphertext, byte[] key) throws GeneralSecurityException { + Cipher cipher = Cipher.getInstance("AES/ECB/NoPadding", Drongo.getProvider()); + SecretKeySpec aesKey = new SecretKeySpec(key, "AES"); + cipher.init(Cipher.DECRYPT_MODE, aesKey); + return cipher.doFinal(ciphertext); + } +} diff --git a/src/test/java/com/sparrowwallet/drongo/crypto/BIP38Test.java b/src/test/java/com/sparrowwallet/drongo/crypto/BIP38Test.java new file mode 100644 index 0000000..8282f7b --- /dev/null +++ b/src/test/java/com/sparrowwallet/drongo/crypto/BIP38Test.java @@ -0,0 +1,33 @@ +package com.sparrowwallet.drongo.crypto; + +import org.junit.Assert; +import org.junit.Test; + +import java.io.UnsupportedEncodingException; +import java.security.GeneralSecurityException; + +public class BIP38Test { + @Test + public void testNoCompressionNoEC() throws GeneralSecurityException, UnsupportedEncodingException { + Assert.assertEquals("5KN7MzqK5wt2TP1fQCYyHBtDrXdJuXbUzm4A9rKAteGu3Qi5CVR", BIP38.decrypt("TestingOneTwoThree", "6PRVWUbkzzsbcVac2qwfssoUJAN1Xhrg6bNk8J7Nzm5H7kxEbn2Nh2ZoGg").toString()); ; + Assert.assertEquals("5HtasZ6ofTHP6HCwTqTkLDuLQisYPah7aUnSKfC7h4hMUVw2gi5", BIP38.decrypt("Satoshi", "6PRNFFkZc2NZ6dJqFfhRoFNMR9Lnyj7dYGrzdgXXVMXcxoKTePPX1dWByq").toString()); ; + } + + @Test + public void testCompressionNoEC() throws GeneralSecurityException, UnsupportedEncodingException { + Assert.assertEquals("L44B5gGEpqEDRS9vVPz7QT35jcBG2r3CZwSwQ4fCewXAhAhqGVpP", BIP38.decrypt("TestingOneTwoThree", "6PYNKZ1EAgYgmQfmNVamxyXVWHzK5s6DGhwP4J5o44cvXdoY7sRzhtpUeo").toString()); ; + Assert.assertEquals("KwYgW8gcxj1JWJXhPSu4Fqwzfhp5Yfi42mdYmMa4XqK7NJxXUSK7", BIP38.decrypt("Satoshi", "6PYLtMnXvfG3oJde97zRyLYFZCYizPU5T3LwgdYJz1fRhh16bU7u6PPmY7").toString()); ; + } + + @Test + public void testCompressionEC() throws GeneralSecurityException, UnsupportedEncodingException { + Assert.assertEquals("5K4caxezwjGCGfnoPTZ8tMcJBLB7Jvyjv4xxeacadhq8nLisLR2", BIP38.decrypt("TestingOneTwoThree", "6PfQu77ygVyJLZjfvMLyhLMQbYnu5uguoJJ4kMCLqWwPEdfpwANVS76gTX").toString()); ; + Assert.assertEquals("5KJ51SgxWaAYR13zd9ReMhJpwrcX47xTJh2D3fGPG9CM8vkv5sH", BIP38.decrypt("Satoshi", "6PfLGnQs6VZnrNpmVKfjotbnQuaJK4KZoPFrAjx1JMJUa1Ft8gnf5WxfKd").toString()); ; + } + + @Test + public void testCompressionECLot() throws GeneralSecurityException, UnsupportedEncodingException { + Assert.assertEquals("5JLdxTtcTHcfYcmJsNVy1v2PMDx432JPoYcBTVVRHpPaxUrdtf8", BIP38.decrypt("MOLON LABE", "6PgNBNNzDkKdhkT6uJntUXwwzQV8Rr2tZcbkDcuC9DZRsS6AtHts4Ypo1j").toString()); ; + Assert.assertEquals("5KMKKuUmAkiNbA3DazMQiLfDq47qs8MAEThm4yL8R2PhV1ov33D", BIP38.decrypt("ΜΟΛΩΝ ΛΑΒΕ", "6PgGWtx25kUg8QWvwuJAgorN6k9FbE25rv5dMRwu5SKMnfpfVe5mar2ngH").toString()); ; + } +} From b4b2534e7a69c272a4d8b089cd88b3502f6d4b39 Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Wed, 20 Jul 2022 16:54:39 +0200 Subject: [PATCH 138/155] add fee rate retreival to blocktransaction --- .../sparrowwallet/drongo/wallet/BlockTransaction.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/BlockTransaction.java b/src/main/java/com/sparrowwallet/drongo/wallet/BlockTransaction.java index dec93b9..9e581d9 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/BlockTransaction.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/BlockTransaction.java @@ -53,6 +53,15 @@ public class BlockTransaction extends BlockTransactionHash implements Comparable return Collections.unmodifiableSet(funding); } + public Double getFeeRate() { + if(getFee() != null && transaction != null) { + double vSize = transaction.getVirtualSize(); + return getFee() / vSize; + } + + return null; + } + @Override public int compareTo(BlockTransaction blkTx) { int blockOrder = compareBlockOrder(blkTx); From f7fc559136b430b11a5f0498aef6369e5e7bd32e Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Thu, 21 Jul 2022 09:48:42 +0200 Subject: [PATCH 139/155] upgrade to gradle 7.5 --- gradle/wrapper/gradle-wrapper.jar | Bin 59203 -> 60756 bytes gradle/wrapper/gradle-wrapper.properties | 2 +- gradlew | 275 ++++++++++++++--------- gradlew.bat | 14 +- 4 files changed, 174 insertions(+), 117 deletions(-) diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index e708b1c023ec8b20f512888fe07c5bd3ff77bb8f..249e5832f090a2944b7473328c07c9755baa3196 100644 GIT binary patch delta 21931 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 delta 20228 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 \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG=`dirname "$PRG"`"/$link" - fi +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac done -SAVED="`pwd`" -cd "`dirname \"$PRG\"`/" >/dev/null -APP_HOME="`pwd -P`" -cd "$SAVED" >/dev/null + +APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit APP_NAME="Gradle" -APP_BASE_NAME=`basename "$0"` +APP_BASE_NAME=${0##*/} # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD="maximum" +MAX_FD=maximum warn () { echo "$*" -} +} >&2 die () { echo echo "$*" echo exit 1 -} +} >&2 # OS specific support (must be 'true' or 'false'). cygwin=false msys=false darwin=false nonstop=false -case "`uname`" in - CYGWIN* ) - cygwin=true - ;; - Darwin* ) - darwin=true - ;; - MINGW* ) - msys=true - ;; - NONSTOP* ) - nonstop=true - ;; +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; esac CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar @@ -87,9 +121,9 @@ CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar if [ -n "$JAVA_HOME" ] ; then if [ -x "$JAVA_HOME/jre/sh/java" ] ; then # IBM's JDK on AIX uses strange locations for the executables - JAVACMD="$JAVA_HOME/jre/sh/java" + JAVACMD=$JAVA_HOME/jre/sh/java else - JAVACMD="$JAVA_HOME/bin/java" + JAVACMD=$JAVA_HOME/bin/java fi if [ ! -x "$JAVACMD" ] ; then die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME @@ -98,7 +132,7 @@ Please set the JAVA_HOME variable in your environment to match the location of your Java installation." fi else - JAVACMD="java" + JAVACMD=java which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. Please set the JAVA_HOME variable in your environment to match the @@ -106,80 +140,101 @@ location of your Java installation." fi # Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then - MAX_FD_LIMIT=`ulimit -H -n` - if [ $? -eq 0 ] ; then - if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then - MAX_FD="$MAX_FD_LIMIT" - fi - ulimit -n $MAX_FD - if [ $? -ne 0 ] ; then - warn "Could not set maximum file descriptor limit: $MAX_FD" - fi - else - warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" - fi -fi - -# For Darwin, add options to specify how the application appears in the dock -if $darwin; then - GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" -fi - -# For Cygwin or MSYS, switch paths to Windows format before running java -if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then - APP_HOME=`cygpath --path --mixed "$APP_HOME"` - CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` - - JAVACMD=`cygpath --unix "$JAVACMD"` - - # We build the pattern for arguments to be converted via cygpath - ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` - SEP="" - for dir in $ROOTDIRSRAW ; do - ROOTDIRS="$ROOTDIRS$SEP$dir" - SEP="|" - done - OURCYGPATTERN="(^($ROOTDIRS))" - # Add a user-defined pattern to the cygpath arguments - if [ "$GRADLE_CYGPATTERN" != "" ] ; then - OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" - fi - # Now convert the arguments - kludge to limit ourselves to /bin/sh - i=0 - for arg in "$@" ; do - CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` - CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option - - if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition - eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` - else - eval `echo args$i`="\"$arg\"" - fi - i=`expr $i + 1` - done - case $i in - 0) set -- ;; - 1) set -- "$args0" ;; - 2) set -- "$args0" "$args1" ;; - 3) set -- "$args0" "$args1" "$args2" ;; - 4) set -- "$args0" "$args1" "$args2" "$args3" ;; - 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; - 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; - 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; - 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; - 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" esac fi -# Escape application args -save () { - for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done - echo " " -} -APP_ARGS=`save "$@"` +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. -# Collect all arguments for the java command, following the shell quoting and substitution rules -eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done +fi + +# Collect all arguments for the java command; +# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of +# shell script including quotes and variable substitutions, so put them in +# double quotes to make sure that they get re-expanded; and +# * put everything else in single quotes, so that it's not re-expanded. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + org.gradle.wrapper.GradleWrapperMain \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat index ac1b06f..53a6b23 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -14,7 +14,7 @@ @rem limitations under the License. @rem -@if "%DEBUG%" == "" @echo off +@if "%DEBUG%"=="" @echo off @rem ########################################################################## @rem @rem Gradle startup script for Windows @@ -25,7 +25,7 @@ if "%OS%"=="Windows_NT" setlocal set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. +if "%DIRNAME%"=="" set DIRNAME=. set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% @@ -40,7 +40,7 @@ if defined JAVA_HOME goto findJavaFromJavaHome set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto execute +if %ERRORLEVEL% equ 0 goto execute echo. echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. @@ -75,13 +75,15 @@ set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar :end @rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd +if %ERRORLEVEL% equ 0 goto mainEnd :fail rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% :mainEnd if "%OS%"=="Windows_NT" endlocal From 40dab5933702c5b12913337dc618a68652c445e4 Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Thu, 21 Jul 2022 10:44:06 +0200 Subject: [PATCH 140/155] remove deprecated finalize method --- .../java/com/sparrowwallet/drongo/SecureString.java | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/src/main/java/com/sparrowwallet/drongo/SecureString.java b/src/main/java/com/sparrowwallet/drongo/SecureString.java index ca2b396..2cbb608 100644 --- a/src/main/java/com/sparrowwallet/drongo/SecureString.java +++ b/src/main/java/com/sparrowwallet/drongo/SecureString.java @@ -73,18 +73,6 @@ public class SecureString implements CharSequence { return "Secure:XXXXX"; } - /** - * Called by garbage collector. - *

    wGKE><-EaQ?#cY;Fb3+E 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

    bUHO$n|v{ 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

    9Kb@Ta+;jD>HC|SI&pAJ< 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

    xEEkIT<)cGX%%16S zsbO>j2rILJ%mR2?v?f|H>?47zOifNMqb1OX>EQf3RxE~FY@lN4)+#3Meif2Q#;}Tq z8{76Uo@c{(oNLdS+}X%avbv z&hjqEDpI8#9msl2#<6M9a3J59T@Fo_&f}a~Q)WXqtQ+Y(zA-0$htiGct95_`aUb)I zIgjz78zTSxYvnihT zJ2%&^aZlNe?~AFr;M<8l%$dKM))#1!c@2tIL+jlDLtMcWO_7zx37?FAGp&5MEU{Vd z1JiQ=v00x7a*hNy>tRDtL4Y+|N$bs8h8iMzcdqAV?OLcf=$3DUW_w6P+_OTJ{$i?W zY*eN4$RKBj+h@4eDV|;L8^&)GkF+Croa;B>emNAT=lNsrVn9#)-!;lD<(}Xf zhLb8X6Jqgh2{Jdl56(xCSq%_t@(ZQeX=p4~*@*kxw1g+-G8{S_PtyTnO|Ae^LV_#* zSs=d!c+M$JXa=5a+G{ev>yQh!6^+?ezA!DJ^h@aYluBui|EnhrAS^5faudK4rPiCU zu-CR=4Es0ENO31+SIz!WS1pFelU;REE{k76Srs7RdnqTDMHYH!FhKU-N%LVItKLJ# z>j2SJ>+D8o%x=U-rqzi~mUW*u$}p}52;!GOwvu31eFmfj;0c9y)polfqN^HgD;l${ zoKjuYbu_Le0m8yeAk#?DLN$;Oz_T;lLi=DC!+sHku6j&%Rn~)YR*7F3z^I!Ir!g&L zS3PEm$8X1=>@|RN7LS=XkmJ=X9DM)@typqUR>NE3XUE{HA%FxvbVcS9h0u8RGF-X? z)r?h!LD0{{=e#d^rxWfYe0PDQ=so?|#>$j%UWNvx|}A(j`4%yQI~rd>9+IT|2P@Wjp}ykT32`y3#Om0Pa6uXBrKv156_`58mh*)2ipb z^FJtR2G7d?dEUt4+tK)#hQ{ncdEShOgf|r~>KG4V9gx)kE2M;{4i?VP`9Q5x2WlcR zX;$S9qk`SC)3jDnAs5|A$RDOc5+nTBF92dmJP70gfai#o7I9j~XzGkEGn%RSDbqTt zHSdG$b5usnHo?XAFXaA{nvL+qcA}$Zm%W_NQu8j;x)lCcC>s#K`JZKCaC#W$bF2OGs88P*e*!)^9WmWAvNzdt}Ma}u)nm5>*U51+Z_>p+y-_R$wX2Ydd6gTC*@C3}48}26H(;eKD z=j&BdZyNcEM~716;rbC*cV&u^`{|7xl&v)kms<@p7vCmTst*HDN6nk2KmBAk{h)%GU)b(UD*k)YLoQGCmujH zKJ#S)f6O0nZ;dxOc2*r0QrD!levH#QMtGgWF}u3fwDE+<^P1t!vN_WAF{pU zn$!~PRB;b$?|6Q-aD~B*(kKoIxft`1X+6%(n6B`RJh*&-+y!0AXClB=7+NGgahpvm z3e^$w*)iTQS|QYt;6%wr$rS)kyw=18*?zAt_Sz&><}@^BTlu+ZEz?#?pl1m{Sg{FO z*@fJlv@$r{O0j)?;995}%xPB*eVlf3@T4>5v@20OoK1T=@T`ZsYEh-%y)UKJlQx%} zkQ`>dn^V>c@k87~Il{&F%U%}0X@pKQ8{Wf^$q`;?206l=@(trdR9x=33(W=GasM^J zFiryGj=RvT;IQ8@$uOn>5*o0n!on^Nd+uZmIUoT`k(r12Tz2AAOgBJ~uSy})Y0@m; zg=qu?_dyQ1gUzGJy>>db1wc^j;|tAf6D-CDGYsPy0C&ax=Eq@Z%vQJ5wCw2WaR@xB)qM@*OA=I< zF$?DzfKsOx7St)sR#$9V&AN71Ltqv_)NU(~Iuca(36N6&PrBCBaT5`JFhZ9Z8ndk| zHm&}MqJ-k;tMD`vAc$!|CX=9*p984?c!F9Jt+a0_!b+hoGc;yfx!JTfjaG_ZgPxZG z!iqH;2!U4efCK@a`C5}$e=j;jkEPnf5AmPD5k1y4y_aA6nhdA@DFY zP~A}=?~`Dq6RyEa*Z`^SfUQnrwz_3F9gk5O@*v;`2z3ttxet&{b&<|Y<<)+HTLran zlJJGfC6J|86FZ!l3Af~oY{B8RLh%d$Ple)<8!kNxM=oxsPKN5BpsYc$X~c|1#IgbuE6g4n1HttU|af{a=bK$B0(*I?dmGpmuufrX|JY+7Xf0tZGz)H zU@5{zfaeRP2_t}uaXZiwR$Ss&g&=Nd%(gPYw4TvcWo8aCKgnga+LX5qqsni(|w7P314@^y%;`_Q%c;6;-l7;{W(B+eMZ>d>FziyZ(# zYyz^L1gr2lkWT@g0xivkwm)YOvFdzXW*nksziB<9HOH0Ufg3<*wh3w;gWS;o&k8Lq zy0E=*yt63NW!O}qIbd2}Yt1)7c9GU>6V&_&av!4R3N1~|?Jiu@xmK4MnbaIKtpHBG zqM9#3cAwU46V&`AazCf$om!fj+XEV*d9N-r=2LU7X>HY-yWNJF2oPp$f||!7cMQOD zP)k#DX~*73UoS_{WmHh}c+>i)*1Q<9H)+i_LCu?y`v^6UQ_^A*Rdm#xugi>PYA!IX zX;-Lfz5>~ov}T*2=073#OKP60rCI0pn_#gBidC6uXe?IDLUhC=(|S%@>AnnC%mC3d zHbEJ zXx9O?%owVUg+97m`Q90W)KjXILF(0ErPG|7PvGH)p$3)rnG_VB-nscaUXGaVT)zjq z{>=}kqDS5oPo!d3%V8EjYKqP>8}6HkuRDr2vfmUBq~1kMUjf93>*F`)&^?zfN8kjA z5f?&l-cRowcRRMc70BBVNA16$bAAn*M*|?{E;77%fDU*0UHEUifEeM1-~5(&3s&L@ z2;eFa#J(A8GKjro72Xp7TqT0oH?u_y>sbRIu^O2oT79!f1gr0s8^#-etN1Q|+?y+e zWAAehoH`(R7p~&t-qKIU%96!v1qZ}S_jou~mRyfGJML}q0yrKYmG$DwiSH<~d{r-T z|NXAM{$Aay1g|C@v~R0=;kNwu`m%ggve*y)plmg*x=CyY?}_hb`6Bqf;JP(vEzW6+j*)!B+%d0`e>%iX!T@z}nTW2Bm5#u4S&z3ETP| zYw=p(ZdIyY3v_L+E$bvMSHz2foD?$Y$d@*e3}^WLwWUPAsTi;+2Auizh5>? zK57*ahiHmnxywyqS3l&Fr!m+oYZ03%vl^(#G*#s!7h zl{jI=;JFtdG}r_+>_qOb z0kS@s_eu?Tbwgpcd;Y-M7gP#91pf(u&}I|V#s^0Rz>}>N(L2}LuTF|a=c_WOp)uRY zVatbG7@;>4YK8zh5;QU!xw8PC+2KaoLmgpczHLNfwvi*&eYr~SdZ<|k5Jqf*Ms^{0 zC%{t@Zlpan5k|^%nV~V;$WiN?T&4FE)O-jKMr?vcTv%~*B%V!L5xeWOeIgS^YIT{R zG26&7Yigd-I}BvTW70zhgzqqI2({wJZZm5pC7Xn6VH!-QB3lTiQaMLt5QCJ?}qy>#wGGC z(#>w{O7iJ?v0{49kAPh=xi&Y+T}wVFN0nV=ii>x!bCfD!$hCPpFLU(<%Ujsn>~geJ z$ua){y9$O&Zxej*{)C-RS4e9mY7=23_O2?G7s&1LSV-|O;QFiL5l3gW=T3KQf~M_Z zntCAOU>68YHWy>Ny$oQW@`x{jz)_VsF2DtAx$W;{YU*BQmb zuKtzevAbIAu?&O^*LlUpzJ6V)l7q^=(fcNQ^dsAl;c8af0QT3~)x(+Euc5b?4lwG3U%W(S;>?$6%HLn8?ypijKn*P*qbB9vdR%o!&)sFJx*AYjU z!x6UZ5OMI?GP!H`WP&*O;{qKA@3`_i8?Fk}P4m&>L>t%z>7{kBcG-9vW$G-ez5jWwu1>3tMx8nqFdpph2j zenKNH;YP|kZXjoMnV~V;$TL=jHWK?VIs+hDViPnn1-S(PkD(kMCS`b}8{jh=D&Q^US?kWrImb4ligyEI3j0y&8kWy~#4xe|F$lkqS5}R@gB6H)0CFzg z`8em|w4dWKEgh7kb~U#C*L)n`FX5kNdtzX!+~5_~V{aUk0OR;f~? zhd|y`BC0j|?f4Rp`c$!DWTQ554|OpQA@^NKzD-qcfcP7bvm{;s(W4gEd4MRgJ3mCu z6`(EyIKKo@3SdZb8)n zQIwDT2Xgr3ET>}*p0^`=Dj=da2yMtRT4*TE3eiwHN`4QPw*f|M#U(oysTczy*idxQ7`kaqx4WOI&0j=Kp>0yzC3Mgkc`Vk(GTKzrlSEGLV)BjuX1fZkEqh|h{3?jYF6r|;m2J#Z}~Ks-%-@w+aA+c!nA|8Yh7qC&4a^ zd>ms55M4L|$S{ByjS6KCqd|3gH0GgvE(NISJ|OpypsKflyhVbe@pmA91z@3VQuBy! zZ9I({u}ezOpd%~g?0MWTyGgHnb`zo)EOG`bXH;imL{W{nhPX{dFu`D@&lC7UJ0OY$ zB3KE6$_9w5l(Y71YR9M*&v52OWK#*RQdWU|B|u)KoVSf>Y@CpQjCzmhSKxgNAg)s0 z1@bltUZrRP0ug+VX@qK?WyI#7;#;kcXp^@me}~9lDaPBA#O+WHu<{kZzCF>g0@U#u zqeT^Cxl-L4YXl!uGuq05^jLr(8h})jV2tv2Ab$mT&MRSbeMHz3RG~Q5o`~gCTy8z2 z6({e2#{dY$HbKP`kUJjWNms%`ar>7+h2l(G@op-<$NEYuz7wLiYsEG}#lJxARw~X9 zS3KMPISHY-$X0xoitn|qL;xcy`Fn`Is}6@QQ1zfbNHRhVAOZvaCce?qPc7&-$I8AmOc&7Tgt4&)qWEnbM%f-eX26-=hw^h2JjYTW@18Tj+uhPtvKSr3o5yKT1=wfbCl7WEeF7cZ- zfopiOqGVtxCF6x;;6Czp5*PVFagpCiy!D@Z z=Bp>`V7Y>)iO8q0FaQa?971k7YxW2-76Zg<&){4|vC+T5rVU8wkt#TA*o}|vM&JoZ zxEMqC_6ZUTK8v~JnXYzNV(s@t!S;CHOzpGAcMMl@^Ppk&&ycrD|NIwEAibvgJ)158$6Gmr;JusN+j{y~DxS^PWv zs0=_f$0pdESCRWHOV}J;V(nDMC;d)3P+o%ZM|)B9p9>YHRnt)#wTC>ji=41hTR#4I31LW)$qaRku=;?lroSQSjrOF*f>^RhC zve{(>>%-xH1Lj``7^``-J)jr|Qxu<=Vl(0?u*UI(8^@Dv98a_Ze#qCEr`pau&5Bd( z87MprDC8;jkkXkXRmu}>`t$fk1^^%Nra_6iyukAy)-c<&I?qE58Pe2&tp?DM;6DB; za$f;>)@f;mH0{q)#PjqGs?2FTPbJ#@!rT=T5~RB0{~Hfo1o@fk$Vd@?+(}8{`Cr>d5^7mH#OtEk>u-?vU~r;^E8N^3r^XDyP+-&EmfyQy559W=@JsOg2W`e|GNzhQU2Xs)Hr9YF4jXOs-i zpb87y7taV8n0XTXI{;!|d>_brB-osP1NkQj?u(;d#fcCgnqw1e&RpbP%@Xd5y2LuK zOzM46oCfWEQ8z;Gi*mk(?Tg$2j1>TU_=+ZaI?e1diapJS-UEAU0P;7SMkq!cGRZi= zwB8^ix30&*v<)D(u6KdFO@dpOCZZ@~f0;U{RB`9p0VVA_7oP#jpKvNvJbLGnugo*x zH{AQMY0tN-6MGq|lVMu!g)sUliq69NUs!`-RLpUCi8%7cjvoh#-h;fH;`n2V^b4)1su&PvPHq6q?VfGMCXp z&3#O3z#^sWS;#(3Wi)dh$T<@9)nnd3mphGG&Ez`413 zwQ*&UYIFYsxEj_IVa;1I`df=WPjcUEVkPDFgmd~#JOep&D>Cp2St7x)B?E@UGmx0i z#50iOH{o9aF~W0xb``zp*^3VRPfGT{?a9JnpH}qg+mk2uhpw-c^!YoJU+xO} zoAzfd%a6;n+OC$GHh09NQg0mXe@j`xMAY5_D_@f528?J_s#Te1_p0!5JLYR;<*m15YVH80vWl z?E;8u*8+K%1pRT+``FC@qT0^^d6ERHJ>>(#$ODLKKM&+-K%dnpDTJwN*oj;Nf)~eD zv#Lf1KkVFiuYEvql`4+o@RBb=77N|Axp{@SNZ**uRpCy?6{+H)xBpmkofTZpjqp#_ z&Yw2)nQ*Gh&?~O=Fhi*rDSBRcg{a;uNH#3pySln6F0yMI{T&+Cq7-2_P#FIs4L>m# zB0AlQjv2ik8}MQDA;262q6ElN5#2@dw4z;-!Abz}WJ&<((@#B3fex{c~_DH;kqkg<^ z7m9b1pAX-T0Qmrb`AI8UqLZ;360r|j-)SrV0@FV!#h(aFIf`Bc2rDnPTN%}EWf_V~ z0K!TwkZORk5?i9{RSt>RpIb9;0VCVe45pVUMJrzd`5YjuRM;}HquZ@S9mBK+2rI*Y zWC9omVdWXOX)7Aj$GX`1s0V0~>+@;|%%+g*fNBRr<{c=uV*uCY1Nf<8*J)MGUtRm7 zDi>RTD94h((-cnq88S-8S1Ku`+e)c!OQcpAIfxfCT$>MdkZGYzNVSzRIUQugns9AC zA!L+=ZHk+ZZ5AnRaUG%FlztFxYgRlwrra-iT$^DF2Nl)2BVim*Xb!Z1M;V;kU1wFf za|14ploh#7#dlR*n@_jb2@ji;vzUpWH@m~I^Z@V|KiU^K#ixt+Eal5wE7XAT->u1^ zi{)VA6Z4&Q3s*41hI=qrYXBVy?({p5`vkzVPAg&z(SExxUeeg4%AAJAY$Io_L)yr3 zs5z>Q*aVHVA@?GUG=v*z4=03??YiuLQTFcfT2JZ!|NB0?v+uq4-QJyc+b-E1D1>B3 zlS&97bfihBkPwoP&Im1uRkWecbIVANk$iWj7SClq7_d48?UYP_{e>Qc4PsDVma1 z!7mC}qU2xkEkVg8h`A^zNeC&qAJ==OlfQS$HjKS9ZRhqaGDcKSPNl9T2?p{lp5L#-r$2z!jk186a;(N~~i)7UAiLBiLGwP2486rYP z{WOp%K*w#v7uKdad&#o!uR>zdx^1^a7ocf*aZk?`Z2WLsjObWQgMT^-SZ#>ucHG_= z?_;`{xZJ78Y31xikQYQKrkg>&1v+jUz7W&?MKSG$M8#BnMc9g+!?-%){~b?z>oxfE zt`ogwMM)}NuDGd-ZTTK+M1Xa%y+L{c*2S*!LNn3kqAvC%yhn*&!^Iqs%K;`4v+iNN z%!lA=b9dC_Q*qyO;Jg*DrEoo@VD&{rPLD3EO#&?^eW9ewRz5>dKxXSZb@wyXD&dl%U znIz~h4FuT=re*}ZZsZeC`Zy;b!k7syp{=%vR77UT>3!?x(sS^BcM9ms;?ri^AmLdfW2Y|9uR7z)c>mw;hkU z|77hHs93qPB%PyOkRIz;8V1}%;ri<|QHVc?qD^ws#gvNcmr`g^?+>~B095FEA{Ezv zp>K68{fJw;K!rXlQgQu{>)<==V>&gU=8UM~hQ#cz;Th|S8-t-fl{tgxmioL829nJv zZVEGsNj9UnDahBola}&eTso1et!1XCKIQdr!10xjB@g*=X1@!3 z55-*r->2|=Y|GR5`?Kkc&m6Al?OeUBnNUVYhw3{t}S-3StS!og&sl`~vd5h<6~S zZDa=?NWBEH5#$q~ToEYU^K#XtHIqww7_wwa>A{9e=OIUqA#JV-!6I@4Y}u7Sfj> zpNaT!4(pm*}%B7~X<_c>XGfHoE1oct>H z$=#|jsz5EiW_=2XvTJQteyw#D}`Z!0V&%-jbL!Q~Mi@3gM$hE|Al`vJ@>bZ0% zZaXrtNY=db8b!mZ$N7qXMRcV1_I)beW?Zk-|G}86`afj5`laVJYQK^>;LubZ2bwb1 z_M_tp=?XJNH-1Zy_3z}@O%!dXpew5FN`9RapE^kef=>_9-5p510C6J7@gi10Tn=)n zh=(DTf;=GNZir1FUjpS4R;q*1bZOH|zjDZoY#*;p+X&mCh?H{*ONj{2-cg>}A)ZSX z`c96ELs^a|%AV|fuj`wR4)eZN5;oV+^Y&3ZzDR=Uu#D3=bAFAr*Ei2|6tG(P@vEF1 zS6)bZWM(z}1{yHqWnYkPB4oUb1Q`Kz41#JcFb$^g7QR;@Giyt6M17L&72bHM=L%+) zJ4$a6&Gz;EiuN`3AWo_%t{5*Rn}&H`?Wp|G`}#`{Rxh+GLoG?|#e)F8#)F;-~O@Z@tu~j;y9GRlF3BR-dZg`gXGYW}whpZ-)97C>N{s)-AuqvIDHQJ`kh_ zfMksq9kl$&kMT#6U&~)1$!hK^V0u!FIaQIqo{#NUEo8kO?=S^ERf|vI`53TjQTiRd zI$+geFOWTfas??=g??U?szM4WNkRIo!RDqHiQ*xiFH{Cs*o9gt$0<4 z-Z4aAh+-s@dkV;fB2;Sw(Q(`0g{V#~is}*{RoA?n{m5Vw&)z1Qu5ns4Er)|Y+xg15 zxAR{sYRch7#AG25<*uR%FY|KJJR}I;+VaY2@V$f2%kcb7v3?1n`(_43AoVQ79U!-f zSO)P=katDg2eJM4lsS-E2r(4oXrNq@OFzLyt9{w!UZWbql~Y|oxT(7>K@?idnj*%> z9AjuP=__r~FKI8Y_?oO%`j(gJ3T`f~bX}3}zl(i2Ue9vC#v<>eR%q#rJZh|ckabBO z1*{G){VLv%uOz>kXiLPlLKczUg~|YJg}eyzJkW95V74t%@-Na3*tUpr#`Z;q;xZUO zwf03KKQd+#tWtjbD*hC2R#Dj^1OcW1MyvyQM}#K4d;gou2S8b+7eoS!H~LLU=inCw zEK#x~9y;C2Jqa-<0;VJ(q~s1^-1tNU@Sh$(cq=$%sTrz!D|*#XHXMk>4LN`vI1cgpiVHxK5Fham7js>jS1_VxlBq ziIV%{SwYEzh`Bc?NeC&~gzJ}5GOJigVWlHm>8)f<`yNCdW!6YTw7aNfy|iYDtX6wQ zHKq3)qjln}qRq5nLX!YD{tO!tOz$hA9cP+M-|@k`Rf}bV>rLnjv-7ietOKoWlJ70aG4u6X>zWXafBx^!;+% zke8$ha@*@i`YNE}tG(oQwcH+rzDsT!I?3%`x$W{3(+Qv=Um>^02B7_J=v(Ec^R5+R zpV#EO?N;;x_EbZ~Y2m4c8Etpp9iG$uG6P#PkGOBkwoTmMM&6r%#eIE<`|r4H1^8vR`n=TK=@%5JI=Lk& zw+K{H8)dUTZJHBpPc9dDFfFrdy{{znF81|LnAr1>8;h7m7c;qKP1~j0TEuf%10Ht@ z$)a+hMLSYd7B}F5$kut^Q;%d#pn_l;=e2mW_`IL4@ozEdd%x9O+TjJBkoidj3!~yAwHV5hmcyrrWZgZ?1dDa$m zn=|B`*YPQeKo8C>iS zbK`A%fEu-QH$KsnNMGaeiN3~j@1YGgH+_wl7;gF+|3i2yTO+ElHKJ&j{kk%{y2xp; zWt0~XU3t-gx4@Y{7i^5ex->g zbVK57^O^9BP5S-iQaA(c#pT9uGN9n z;3wE(U8|4i0V_{*_#T)Kl_L$eTL6`#tS@X;LeE?|+7(o%p~}^x^QoUmTJ!eQlFFkG z7M@pu9DPy}-=ohnREayf-pbw*cl5o#!R+#VKvBLAu>9pbh`xT=x@7)#nEF$9Mf(2v z0T;P8$XbH^QVX>FR80o%-(4Aa=KpbL6{s);`yVE~E1(|(s+BMMA1|lIzc4ogs#S3N zpDm|RkjKeMao_(UIW2>H$ehGwCDG_t)B-iS6HwVF87*uysXQPVO{`xY;v-AXdm6Dn zDAw(7>z9v3#9)cazU6t2pdbG~ypwJLV`@m0U0>u~O-d7Qt%_$i7x{KC_GSBXI;-pv zW0QUoKCGetM)_A3`A=%-zh3^Wy}x?A8;bq4U=nxszF{HBUEz=|KT>`T^NazF=en{}Z7U8|67rc9;gZLGU;WIPU2= z{g40`KJN1)o!)6jTpQ(6O|DdLp_Dc{!utHWmvThvIosw~J%&8wH!exV@37k$sp{wK zErR`jV|@y!*4zKp&z*A4NDdG{F9Xc_s(#Mi1n%`apPmHl+*I{*3$@L$0{Sm<8_xJs z{oGS3jBfwIDg!E>rTJGsw@LaYK%WI9#iLMRtzxKFlXCtIjpEj)x~Ok# zUOXJS3Z%;9-kfS(azZ&fJ1^6(RzGb?Ug~u;Pm=r`GisOQr|lu+KNFSv0hi>bhw0?) z*U%dQm*l6-xZDjpZYQ8ZZ-G@mZN}v^=nLd#Nq+i%CHXbz7lDIUdDUBP427!Va%DS6 zw?~yUPQ(r2A78v1%0H@CUDI6=e~U%F_7s=sdF~&z?vr^T^0(LRT>Xqy}Wzp#W^Fs`{3@LeI9B;B6=l6gfy%#2emq@hMGOB%n^7yaE82Fs% zyW$lRt%%P>(rk$q@fyg>A{6n;T#EG=BHk$o`X6f<-Gg5gutdq?xa~DwNpHmT1WZXn zNXZynPnME?L6DSmYIqD`NbrjSmMFP9zAPx2kCd8%w~4)3->WRbIW8K;nZfM?Uy(Fz zzsm=5r|e|@ulK%MU3kI!URtTH-1TRSo^hzWS{5ko7iHuOQXhA<`napCn;6DLYyDQ+ zUy{5)J*w;DuCkABEFy*T0oT;8`lIacZe@IH7N}UegCt#~=Km=4p8zvas;@4XD6@h-@lB2*;R zd0sXK$|9dnq@N|fq)4oCm3Y5Q6tG0ewQ)a^Z*uz~rY~T`l^~akkdjwGUINOhiZTIL3eTwhW7ftJ-8DI4nGxHy(az6^Rnp`Wl);bZ~cK@cr z+qu)hE2p)cpcI{&)QQFu=sE}Zq){h4mh`q~m%e`;#c&H;Un2T5AaxByr)C^@1X7nk zOaZw7h)4L~?&7bX+v_km7LdkAmL(Qa)5d!?mM?ZEyC%fx`RKSGpGT1LFc9UY%;5eH zZ#w8lj_;vtExq)5_*UcdPk7z~QY#=zuqGlPrAI9%f}Ad5F~kob--);hVsML8bSRLT z3$X#@L!exeOW(pJQ@?0h?qiUkwNbPPzwP!YKS^5K%}hmIt9al6NL4``4|1%CQiz8^ z?iKMn0%}`Q^?}sCAZ`P>9w?Wv(mmiMKc;0%eA4#A;XkBa_0BCA%FOTXeN}DSqg}r0 zm%_4K346!=i+B!gz>_Rs#KSyKsM$^iJrjM?SnoILXD8pS!?>jhX8 zd=j4J3Z&bZAAx+JK-Noq?E|HwfF-@e>G4?-psuKFdkPC^NT`=M4A(<}vR{KBbw%48 zfz0|&Aj7`0t96NzGvYUck_!=YUQm({Qt~*ik4i~%ADl8Pz6D|_X`LtuSfXTH+@0>k zBL4+qJ`G9|LP~b3p*{d*or{&sPWn4j(mnV^0ZWve8Q&I^3`NX9z%(X=lw5~vy_EC| zf|Qbi?U9}9vr$XYk0MXCb3C>7ChxAL=rZv$ z+Ua(-srpc}i7#)9aRIc|(oA(f-$!qq?)u!rl0G-5#8i$%13%6S?nX;ECT?^ygvQ~A z5OE*i`pUTpUu|djhR1t|PkrT=@O)u>I@6RL737T<--vjg__RyjxE;L@kkXl^ULgC4 z(AlOlKu!b76~uPSuY;-wY`1(l$YTI8k%sPGLpoY14adh{1q~Zv`W!F~E!%Ti1~3f= zgB%2uE68>_J!O*5#OVwG$+{%gKam`1JUAild<${c9kJVBx)rcHV$Xy8O@!`$V0u2e(`5w4-2g()%L1wKqeARWa_sc{9OOzZL{}_~v zMa-C>Bq5|^9+Fkkdie)kW#X? zVM^8qzbIhIfPZv+Z&1>FC$bE%>`DkJ>4|F(z)k-uN2?_12cj-2z5(&KLBi?qj13Y3 z(MJ+WGvj@)#aAk3`Z})Rt|>KJ9g4Hgla=ypXa^d~x-{Tnz>Guf-`L2RaJDj~)+)n; zrLn}im)N0cO$m>&@%C7at9t8+jwpRi2~&XdHI-Uwi#k1u`Bc46J|&CA7GtXSIm9i^ zPum5bo%5;XiO=<8ho3Adnbi`B# ztR#N``A&q&p?{}TbU0A9I0#a8>DO>XdBFQ+qJSkzYUA&MlIe(<1elWdK;9G~C0%ym z)Dlp(qF6~`M2Y8mcir=*@G%t!6c$<1^^=NLS#&Qvsyka&Z41liN*{KB%VzRfCaufo z7G{@^L-h#2_YyP>Ra>1VIf)QB%_2`(>kmB}%H}ek8->c0^6Uq~r^b z&w#QK#Y(y-rFU?M`)@?+zcSX%fd*?kEZSwNmiwBxrCY7Q*v3V56Z@8E{?t?O`=gda zo7)m#lbNcQQKuJM6DXfgy+Q!zlRrYaYXS136(Fi>+!2S@tgM!ga6Ls~TtDk>Usn0o zdT3nVi5{dGQ1NyLg&Lx9IEUr=rFs@!!OXulUT)`NJ`M#cz9ioH*QO3Y)0!@vPX}x{ zGymG1_LYFH&;X-$evKc)7fq=-CCb0z}y>r>`c$W+5C}7Qf z-OYbl+V2iZ{qi?R;ohm}Y{1@GS_<-j2)%Q;3FJ#49^nNwm~PobL9?wPir|}xYN`1x+Q!o*P1h;v2;3F0>lDL5hKbO1ii<&J0#R-m zHEf)ZTRIvq3GL!XB;i$j?t^EE0%@)Fb&yvTD4y>FTtPC`)QF1mMoW%M5?KKY%{>3l zc+b0#tCn594@mgOY@hk}GhX zEhTG;mCS2+vT1FiBw&e>58|JLlI4hbEGS6`DOr!}hf=b!SjnP>O11<)KIcTv@=KI_ z7@x4%XIJBW$uhvQDdKDyJeun~+kj^_Gojhu_nn8L=qvAQ1`W-UJt6;rO54#3ty32)OXv)V zi?@AdA*jS>fNss~=Y0L(=(d%#aIe9!e&rOcT{6$gHupg`-p66!1_CdkmWF1kx9_BC zJh@v}T1y|g(t7BAzK52(eyIg|nbAhm{7TzgI*Xhg4Y(e9<=~f9`MdM^Q`}q+z4C1J z&r5FhDR)mz=Eb9&}2378MvMVj7arLMZbwqwLB0)F9?@C-~*HY zxy;I>?vI=6-M5ef2L}xzbex~H>0>DRp;|hAmF#F;a%E$R?q1B7{0b|&E`}Sjj zGAX(hwn;Vt?Pme5=vMSs(ft|vez|F%DZgT@itcOZjdHVMS}|KyV7J~34M4?PEJ)^8 zEK=BM&=&v)hg#zzyN&%utl1yK%%JgvT{3n6Cc0RB4 z1!_sI7EZI*^fsaPMMcN#glYDw-tm3-R4(9Z;k0vbZn9HbyUmUa0ZVk1$$x7y}e*8{D6epEoVr+N;oE{+E#GI#f4|sF$BZ&)CWHgoFHU zUVE9MVyC+Mcz^l^kM#`ETo#{pKhe~w?tc@j?-VmVbkq58j(`Gox_cVS zb@*Hb_|x6HxGW%JPE!kel-YQPSC$d zmIOCr5h4$m;L}0I0%e^-V8wWB(ywPX_!fB8Gn|A(o~ns0P-xMCYNAznog(1$Pl>PS zxB4SX>=M)vW(lf92Sr(3kYnW^85jWdK@b_SGOX8bbOKvmWo=v--pEiipEPO+o zmL>8_qKJJ}A4=}c==EKr;^>oiSK{|d+|}6TA}ushjT581uWM@V_>Hn*u&wwg{T$x( zHAqLEXBdCjw^htTTT(IH)R zE%y%_>!_uSZp=x~?5(p>3#d#t0M!%r?uwfol>QR>Gr8Fu_)MDvcVfA$9pJ{cGi?q$ z8G54JKF&+m%^Cw=g?<5WgUi`|@Yu>q_SjLJ+$*e0D;jfsvg@?l;cuo zs~*81`PH=wN@dqaI6I^R?D@LAUdHt#5`Qe<%AoFOq8T3EprbF%dy1z=^sKMw3>`;5Y z?)7!>eE|I?;L5ODQigV@J-<&<#vE$T?`!74;2~H?Ku*b8>8&pY)RWQEJ2&fLN_k&= zu7+hU;B4yg=ea`c;QmGV!z(w#x$SeJ+p=wAQ$K>dhXJ#xE2&myQ?JA29cf}1>Wk+2 zUKe-8RP&C=RsV%J4aDcrp$rfJ_Zd8oDpgOs3)RKl+ESJ3;(1hAhBx3*AG)m>yNb( zh-SKfRQuJB`DZO*vGvoLWc}$tmF#64hl%6dW2odnmA+YocI#e+INe zfYexs+d*yxvS0hq8hWY;S6t|vZS%h2Y}+NZ8UU%+?)}2%$ks0%)pkNPZvkE<)iPPu zA$+a0H6Ucl)i7XH17)2;=!UCH_I_b!@0W=NNb-)U_=_O*FB7($urf{?5|aEQt}+nIh80VWo=lc_I{S>0&26rRNL@cdWkY^gRxr%2D50!tvxw zn6K9#Pn-eQGSexWssD<@X22R@rqBp0C!RSzs>-_dHRlA5Q32Mz`uIM8NuFwK<5XFP z<-|mhg^0LtZK?dxr**8yu^eSJvY157ZNFxuDJ#}T6T)tGg-a;?SnQv2$kXbV`F z@r1V44c@&0Yiq}W{85D3S|HG2pE#YD$O;$(y8Wtnws)pdp^tQ2O!%3SaVW%}K<)Ow~?%p05&nW7(`o}Wh;Xu zHLSveRiD20H$RO$jLz2+F~t*Mi%$O2F2^S9!6SC}2ri|1aJb4VJp&PQu&)j93VAiwL#) zk3c>E%HHyVNKSEv_R?bexLaswZ$6#U z1R85p9wPgZAIp3m3+tp+U&L>%z(WJ{&#?al*Z|$;48Dp5*Z_SH$N@lhqz|qE`U%1n z2Ixx}5ypAnq)(~Un4><$R(mFS?IX7K7X=LU;LJ z1$hzZxNUG-?I|C}at+{DduF-2{C~vdSirCLEcH>~iwHZ@*?$}_m0EQxm%uawFyikZ ze-)u3-|kGhOQ39(4{QyuP~^6D@|O3@Mk^)w(>O;-o2-2ax;J3NWRUYkNbpl2PXJ{b ziv@49jI=rUMVlpfLp(YN-bBzZBumlX<1CiN026#R$eBP{wz!fOj-AH?ywLiTZG;ro zFP!zR*`wX;;Fj|q+f$ua+az%jt9<%ZCe^uSWvI@pd#Yo+8>P1b)vBhe2Wvjx;cRLx zP_3%E`V{So-wk;);41yAKLGSFQ{bf?bVH}+9BgGEC)IT< z)#=Cb;f=)d^{Strg*b2}52L_xBaqq`;u(+?B6frL6y#%|TtPBN;ZibziUU{&)GrYk zu%vHzF8)B`mD{_+z8lbxP?-+Jbudsi%nP#0GU@SPo5g*+yUx|C^|*B!S`Y2#6`#Rj zOWRpgZVl(sS{5j`RFTXl-8ludYdfb<_2fa{k@tD!`IE!#zM0Kcp1eRAYu6d8p0W&$ zI-S-90n75KD+%1(xR&j!KF0zt8|JQ;B4^p@?)buxw(#F)o!QDkuGqUL+Y%%H9!med zy%mEwr28VkzOq?$-?8%l33`*<^p(x3`%WD|I_I2AQv=%0*$ub*+kc6f$T^qXeC(6; zgPa!DLEBQ@m&U(8PoC@X;`Bs5_D85D&qJhM=g)z-^Z-&1Lfi*(r-(Zsnx97j3nV1- z0WOz7=_7Qx?cT(&9qg1agKEc#@zZjr{SA?I_;fp;^);YLABa?c{+tVSCXng`p-(bA zBcct&_7^bM0#eN(#)6Cn`u`DPW_zR_-lWf8kueMUF+B7oj3$#In&^$;CS&-sQ$2tB z`MB^dqe69zQ!8*?2lx9x>Ms!KNkkV&ErI9=vXh8~5c-nl;Xt{a@hYF>gNW7sKuV=H17wN_ zmEIE|kBU$!{si(pV5J$PF;kQ@pB0Br<{&6wS#b%-3=ztTr$L?&p{)1?cQru?AD0y(EL2{sUAEH&r{;F`cTW@LzQl()~NdM2|nwA|5YCb3~|jX9a$)!2_;kM zW&z8DJwQ5(P$mop87M-TFbU**pj=@?CRh|kDhh-1H-sqM2G^~?|BAxOBnlSFN8xX9 zKL=P8z6AL~grd-R8X5tM!rmZz$w6U56tZ<*r0UUA#NmHd$&hq0ecXVlxJriD{dbjQ zmMAlRz1NjVuw)c^&{?R%iQh4bu!f`CKyDVH5$HpZbwJtXkO!J46h1u2yj*9)dhfmy zo$q2BOU57V3JlBDeyIg-5PwGOz2MlZf)2m&bPOv1x30JyD7Pb^4+Sc$8()0nI)u!I zo&}7Xmd)$Lva{k?axjc3)v$;$w$ok0plkwWXiGK;_rzwCY)Wc?_`AX+uEsyzfwih9R$DT3Vg6!%2fNQ+xU!um_>`JbK zT@f1Z`S#9H>0Ih3?$&rONE)vlC0*(@b7aF~$@aji2l=XA;HS3VUgd6m<>TmLP*KZ*Kp(pC>t9DNl8&v-{4D4 zRsA63ZClkZrRr|+JjqG~T<%k>b#HW}5}ssLceWp-HmdvM$DuJcT-;c6lAW|VfrtzO zD!MdNs1vjp{R8xua^r=_0qpzGE01<9hzYK`-m}Uc_yu z9eSjMsQ;b_`vkzPL%)(J3s_GVB-!)172cZxTZeuQ-kWVvk0q69Y&?#_vdUD4q%MFF z7l52A!fGtYV?fz}AV`&IbFx)pN``sAOcbz0$!YQHLCHqMY>-?v@ZIL?B$rn*4&-#8 zY;3WT!cupPBo{NaoO#oI~7eb9tCmUa{JGbVBb+_LPx&0Bhfk4gK z=S_^NdNz|BJ`&bQOE$gQFN9(zy{flG;ji#52kg{owNF^n& zZnOXX^If~b(X>tGM8vqDO$RBcuB22o9cybkyS&&Grp7zSgwANm#p!E2NcxPiv8~d% z@Qp85e4|cZV=T8iDWBS?0OKc4fM_p+zqy`DX?4<`17K>dr-xdd)Ju5&B=*}{o!maf zmAZHsStABoh>A>C_Ii)vj$anx*GQf$saVVu*lU z4={Cm)rjE;!%ORgA74jE-t7bbZO}n)2fQ%Nk^2lg`M(Jp= zhsbD`7V@ife)+eYU#0V_t04Pp=2-3MbC@KtWJFo$ms;@s`@X@~%-Ki9m%5P^1loxW zLp5`bl%;hSZgT*;EL=0^VugA0CYBw5iu=%9Gv`iKso!p9SOaR#iE6I!h87oqCPXz? z`u&F0letJ#bEUujyK!>OnNiK$uop3<$82)9<|^wXKD-5!2gu$184n)#Xs4puHi(}e zcYK?e{so_%Z%svQfYgT&SAtwB;th!RK;9Lx8X~g*MDPs6?jXAWQLf^{C|a7x9xvH9 z=5}}w*(2~d9iA}?G(c=1_lf8W@gI<%MRbQa<~DY~fK+FQzkxg@q84K3g=|Cv<&s=F z78h={Oevk{kg26J95StRjv>77KHrelQ%Y|)WaE_5`wW>qwe(TPGh@4zAoeY)5cAR` z4PjnZGcwoW9a5pQ$0rbh5r7M$Q@QRJutJ#K4hvx}f&U_f>HjK&^`bW9%W3%w@NM!H zbd!(xQ!dxc4`2_&c(0hF#=7`3^Khqu)ku$x^cri%<(5l>E&(;W9XWtq0_p{_AK>m= zZSld_8kXX7;x_LRNcXKq!!uHW^dYagAhQ9xZ#C%%r!*7w*^xCO|536R@O~b!`&Qq8 zYy!}tH_4~^5Lo^@qUGH9L21#E<`#>H9$-hBdw_Hop(D*Ff*cQ&D@fs?@3~%-jxpCG zr7+QPCmAkfq`1lRgk#L^t%|wI8H>)MBs%LAo%7;eYkhQPqwr$I;911K2lB26Mdx>r zUx9K3DMV*!QFPiOMbU9*SuHx5`i+yBw`>z1_jwqLPxe<|N3=tCoEMNx+_ELUc+R5e zCwpIej8}D=vDJI8r-*KG-gr#IcD5T`*^ux0&dn1(xZ;KP>d8?yOxq ze07m0MFUl$+=7T(jMeeA!FDp&Zt=wHJ-=@8h}WG+vGke2R^30;(tuTlT6#@l6gZD%@tW)W!Q{qJSkz=EYwGB^M&*f}kWJq~s1k&ZN_+ljm`!*Z;GMzzv2YE>w(%}l7w3whNnJ?6ami}xCu640|&qg-|oap0_*TZVY(9uDjGsd1VTG{qEtGAyDz-9*V`sGD!yfiTx!&W8hR9 z=P-&j1WvUfFkL^=b}MV9*_hXtHgh1**2ckUjm^HQU%|7(j9N>5g4l7|0fCpsZPrn? zH{o*{K~4oyS3_J4GFQYbh(|#l5itp39mxBDn-;C>=kg~V1uQAi8Sy0&tp*U^i>WUG zB1S?C2W(pOILMD4R#fBO({02Dcxy)32Y4It@!gsc_VL|D=fHcs=Z$Jk z@YB@=ZBTuP5)2w9(>fUFlG>$CjN4Ay{qy5(yxo6{tcJvjbCvh{S!KJe55_H@fg zkP}4c>6R-%W&^GvxAqk$8wD(>nMcR{$senX55xbU1gK_i0og1XL>WutdoKx0`edB1QqGU!=AzPb=cc z=f_g7J+(Xh20xTZKCPW!%1jeot;zbUiQBdfK~xp}_;LD)f9% z#eVA}e5?decigMEJMI;_V=M6HJ`zY)q4bS!_}CZt;ANb22CTrZ2AL~D1^x)g!y;7R z?}NM}LIqy+C`)gEE3UC#b~*}Jl9PSnU!+GRGzk8q03)sksTZN#d zyR|DdV`o>N4k6?93;z~qEOlnU&bD4LnJAnNxO%elbeRDMF6THDQ1OvTy6JU7@ACww z*#K9^cD`Hv-zfeZ2B`>uHU^ zZn@t+CDIz+KO@MefDP}ZD_Fh_v6>=Ab+;U@PB#C$5bQnKqa^!R`&IRoT0plnOAlA8+EtdDn> z={W#-g~~Jo+*zIjig=3rYgySDup^bNRX(M4io70-u4#3m>JZDXHLa%FaVUnCRyP*L z&Q=RmccM;*GP2f`=Tn;$Qtukoln+!7r;z1ibqXs_$nt4+9?N>R@=MjTIW6T+s7H(H z#&lv#*}*FN*uIj>O(6G=@p0XkzOt9^u)9P*NJiWUR9wwUOZg55sPlZ_S!QZL#em)9 zHcA^0lULFxfQmOTAIf)_W)0vu8U;`>V|TgT`C>U|!J)60o4yxPzQfXW$h+>ZEFJ(> z^~>8>H6Q&q79jwu`sF+Ns=tcc+ozn%IgO&r-4mnowtneoiQbAUZ)fd_+2ORBNl|%w zzuC@X%oj%G9m3Z8bo*M?TR#0PLbS&I>e{5{3#x|}LH>;H2LX2hyZOOj{MbGB7;iT-eD((H0`>@yVL)h(UJuRDW1$k4cZ}^r zl&ZH232+l&mH20ne~VB{8Sp&g0Z_Io2vT!go;=B69r7#QkLKvHL`kRkn2o-rT#T5h zfGPO^C+ zL*nk@9%UyM`7UeV%Vxrix!%{-H3rz-=J0i9trqb~r{&Wcaq8yWwluZ88S^X8b=7vc z`$vQS`77>RTI0@lQ{z6ItnLd`PvS0Yd47-@@&f1^I2QknxY<6qW$JI7VRt6WE0Q~t_PNmR6I~owfjb%QrtuBL#6A~#G9pF;oVN2k zx_$U0-br3dDqXEUusE!U=fh$i+o5p}4xj9KbS*HELAGJ*_hKt0cVx!8!zBlyl-~;b zOKcYO{l;Gvg2h(5ZzNuq162=puyBVf&xTT`jsUiwIOe8239R;@6tztOmiE|P%P6n#$WgW;`5lYJr zuW?8ZC>vI+Wo)7)yTO;M?tNw`(WDB{Pw-NT+Yild^<1iKyA*S|io`bvXYifKtk>~B zs*)7uy1A+}??6|Ts@*@T(vt5&RqB?pTW6z)@?k*LIav!gP&+3R*D!Absurn!b<0dq zu(PNoCji@@C8w)YJ-X6g=yk1Tr$xDaGPb$Za^UGvZr@BYG`1WV<+^8*q0vfom``Im z3RsfYJu>lO-}-vojkp%N{BizzQqHakd?mQD?|%=3QCggusM>6M9FkZ&fqCvv(24GC$P zjO!$6SyZg0OQI#a-WTEx_tK1zr+PD9+ri#lBhC@t-L21Gif`nlJ$xz0m%XoBd3O7} z;;HjI8bq%0JmD676!-DIVcF7+L4;#@W(&qv*Ae?rId*q7ZKRJ(XDbeMS~Z(PP1`+F zCt@jyya%Z2-qgY!rCw+Ex3Norc#;=T(%U-6raeZ*AF~gLa(B^ZkM|MCM3t@J`(r#^d{5%j9iDxF)KZ9%AR{c0UJYEG#JZ0H4Uab{ zkan?dh394k(k|9YkY@nf#af>zT1uF(i}e}apNe0v2A2JkEC8r<8$7qRM5@RURcBY} zoC&1AEE;ZP?`4P*AH|z}2vt*YyGoAj5w1V`s>97|^ygY-;;g0-)a-`i zIt(c56hhn3lT6~=^=I#wiE6RTbFDM+=Rxvp!d@06Cxj#~#q}Xc?o%weuxa3~KPQq0 zNb(MuxDU10qWK|V*9FN5A<2y}Z?ZtyuwuzY2gKI;HX-x!6y&+C0z1wRG1`vE*81#J zzcI%%xdKqe4$|%D_*c&p+P*U_FIOA9ohF`Z;>Q=SkDQ5@{Cp0C4bpFIBQgfj6Vo5x7xu5V1(NCg5*rGnmHj zuZl${;r`M09P(3$#cyfr34TECmw=1KZ|MPw#T6eg;{sePeoNbZ!_p7goy5^K{om8R z>CfabgHuk5a{mbqi)OgKAac$AF9cfxxV|72`hs7lmu#f%uJt{Y;kpVEt=YpIAl+7-dT+~dL`rKDDEvKp` zxnJB&S9m5}m)q4dxe{Oqj{ADiT4YpkYruTVVg_yF#cJBdCf7FRF`Vkhrj`9t3v_sN zdoA0*Vr}CQqIx^vM#)WS8ztv{%5?_7wT(?_8znOvNHUHZCBIGwo6a|cZ_+j>R(?i5 z1(*p|>(h{q0+tv@-=*WOTYVv22LHu?Wo1IBkXGUPSD>s*kkqi3HZ9$~UnUAzqGfYB zzA0$gf*f59Ff9ooEnTT7U4XKF#aaqIwrLrVXbD)N<@Bpu6VS@EikM}j=m-X^E$fE#pm0=Y^lte3~rBD2>w8*gf5T;;rxZn3TQf8r_PamZ9=TC_1he;xyPam(^+IkaZ2)Nq% zcc+KVYFAlbaH`VvBisPL+R=X`z)+y%3@Y4aubHcp?TF9I>FwL0IW-%v`S8pGQd1$; zfV={j-M+;K!k<8;f5@j4Ms|D2*YueHM@2l3-ltR1y3d8{uXfX6SnCEr2N|qAS2LRVd9!?+iGI{$A4qpNXclH7ltPoAL2e#Y3%A@H{-w@jTCp3gRT?x2` zaA*2R33PS;uHw4C*w_887qvmmJSXO+{ane?s_d6qpcf5XtDfiN>h0g10avo~T*6LlbAFh6Y5!ZlRDMEwt8jybgW&M5VZR()a?h)QE8+DQ78`JSO zL2|T(>4Jnw%|Q_R115PE$i+a}_+rV0lSU?aQt*pLO7czV_)v<`ge@cNQVEmfpFsXC zLUHc?17AgVXffZ|@dh_`t5hHYdP`Fi9!_SSN< zTz9)V2uJq4AS?YPbXF<165XYW~C>p4}J!R#{d}-v(oiCnA848 z)=L3b3umS6!rQqxoDH-b&kEwD>0|}bbwZc9TK5+i9sq1=5pLd5soo|MbJFo;#K@)= z|AFThps)*e#7``A0_EbhDaClGvjCe?+z4_Vz;M0ACsdaA-3TQ6Tt`fE9vo%6WL-Y! z8Pu1ZcNooOpKBd=U=;WCTwwrrGi*$_sO$fAA+i^`c0AJOeVxlw#<2I%?%MH%t{s0y ztUdr-W?h&btTF89tz1C{+^lqRGKRU#n&L9+5f~l@%zmBfHI+mGOYGNa>G&D6T1|T& z{&xT)cKDgN09Nfz02u+4&GnM3sT3wm@kH+)9{AAlFZ*OJX>L(Ln$K`)p47u-;D#j4 zIz8snd`8+H)VK#dR{&M|&KKbZ>qOMM|3@zXRO#$Kj^`>P`u{>>09@{zk-kojgMQ_V z22iDk(i7wFCG6v6|gf=li{BP*qNw1KyDYIGf}HS{tmbz`qhg|M*&NU z=dKYbmPK zp@{$A2OM>t@&DiP#v?mwhF;~m)vZKQzYgB^;KXm!&>E`J_7dkML~shQJ(aX7eXKgw z?;$^v6E(FeJx)&3v+3x3ph{;haGa<^7oXwqfgEKU;&_#w0_`8CqrO0uzLvH zqc}V$M|}zp$G6pxc5IZ6S^`!2OaP8Q%5e@37Xf|Eg0D(9P04jLE?>#j+FVt7@6;4r z57{mq^#uA_qpM2yOR3d8i^~&$>%CeA3uDRDmS>&K?o!KiEBE2j)l*yA7G=wHt#jBo z)iuUy*BD!rP;$UNWvI$+?;P*P;Vz*498E@R(&4bhw0(4AE7vM*U$<_SOGkNNw=Qcr zUs6FQqR(9Cx}@_@BI`taj+gHmeBUT#uCTLwd!%=K9jj3j&-PdBgu{O6HnYuP$@HfB zeA2`c0`ue2smI7n`{fQuw`i54*6Rz_vk-kTU|+DlALLI!Jk$1)=wWpEl0k_S+~iADUlsQX6dJm(7l{*=Gr4* z(#;B4FePpIW@i!8um(&#H$8>ib35&ymsC8woIqNk-b8>e0b8MN+Bh9m0=7cEFGx3_qiHzp!5IIH*fLrmej{D@-0sV%j+sr}I9hBZ$jzMNT)D zE&`b$LTl-P=(uh8LQFe*$%^UcKBjKJ%4|bbtGN3%@pP-Y7SEFBU%|fj{_JNd>vvDZ zyD4sO;B^mCSqwxaN8QVm#xpVv;!Iu1o~iinVmuD7mtlGl=r6tj_%?bue>I*>~=0{iiYRS>4z(j)Lh#F=qAsdi~T4d*e;{|93OY zF7jMzh9ex8?@wro*(KgrXQC!1zEO5*k^5ZlJ|6y+-d$&+?n~T#f1F+8eYFm=#`~Iy zpXK9l*6%RjW-EQ-w4Afqxcuh^vh|y(vDr|MIxgpg9({u9wW|$uE7?%IWA0@l?|l`s zabD`qtI3Td6djp&pYcMmq^ZidVYR-C%G8%My4HuW+jaW<15GG%?P2^IY_?41+QY$z zvML$HU3|D;)4R@bE+R)qJ`1pA?00%4gXmeU+)t?{;^Lw1=tsC(PB@G6bz4*I+Lp>_Ts^&#b5cJ$o~iJh z50u=Fg!Mj&QPk&b#H7>NzRf78xA1xqo)>`B3lN(@z7_E#M2nW`s2PxY5aIxkUVxKV zP4}T6hms^Olg`c!@}|Nx8E7JTCg(1wI{=gOD#*(~)Ku|m?d24((AaZvx@2RJ`7Z)& zmITRcRZYSHlYI=x5D|*wOpxh-lifX$9Wc5M`{hc~C4Ch;rT=aM+$9N;{W8dlB9#8k zAm56R?3(R4ga~jF)5~prD5C&A>QfnYv$MVXk6YLTPTbX>Yn}Ke@2mR^K7@M)L)l;t zUYs56{gY-!n^SEvpWxVH^m$`M?Wbki-L3dHr;d`(?pBR9r$%c$Y%%T>W;B~q=N+iD zwJy=WuDzNe=%bXKUg)7GJEzgW{p9J6aQ%b(snY|4kRrWGTX6~z0yr~7n^b1~dcEC;oQf)dC;WlZ$whqw@ zq9a6mAcYMXoeVM(h)OnMaAv!^q_b-vdEcb+Z)}geUG}5cVY*GBc7SNIV>;RnNHu}D z8sst&F~t9YY!>k|;x4F7M`r`&l2+OcZ+iQwrTZJQXlm)u$Kx#{I*MC8mfQE+T62ML{;|8KT-J};9e@IP0|#wLYUqD9l}Iy$sr3P z6MBFTQ@}b{RUn%_h;M0$9$C;k5vDz0cIn|D{Y1zvJqP4Wpkojef){SrkM$~Kmrh5b z>bSFyHKN;ROX7*1C)m&Ka=rFS+^5xoe>w_SZHVTF@d4F7nhy|>`xG;o&#!~LCPLBN z3bF<0xNY!4G-nq@b0;J!nr`LPMH3@Ap1(~rwRvidm^Nh}zV-f0F{qs-AH{z{kZl6* z-HtIFuub6MAjbf<3B1LJVH21zVH5azyss0#Hi4f4c>>_OG~68n-cxn(`EsCQ(^+hcp%D#veb(MyTYri zaMl+klHKYftS#l^ysz6MwiywXS|2~Rjb-=ctLA@j5zv8=3w?lOf|RZGzIq+urebkw zL41hGd*5>pOZmm#)_0Di?dd09#WKVLC)?!Ewy1uYs1Iq+ZAitPYe>7+;%+3V*8>d+ zEzCWO>(fBl0v{U5#V-|@h-WVh& zgd{(Q>$8%)p;&U^gi1Da%`&M@M4rmQikIC89WJ+%f2(}|t%<`0o=JmW*HX8Np$b1v9(dZr7Jtm7OMDG zCdFqZRh#7OW=zK1-&1k>Hom0R6Mh|FCDm#-Gyqmo2ZHn#p^};oG8u6DB;&k179l*A zn2vu-#d9QEoy(I1cuW#R{08!~2xW8c&a6rUWmAJBWpm*+vh6L*@_v~pV2PGhsrb8~ z7yWvO~PP`s6(2P$;!73m(kr=vDNm2OxOZn%ncD-NH?v6Ys|A4#3AVCg;6 z(Z)SOIX{xRLFL@J3$`_&a$Xip!p+lF(943sIB$lP^e`V8rqn9wr&4jg)|Yg}Ug;tTmnk}s(|%NXOzAIlCB??d58b~_r{h2G9N=+26C~8uOU`} ztPrskV%NHK)DFn5^pR4rJx}tI!r@Ds)1&MwMc$tld#BH*0nhK|%BkZy>F5{lds#M$ zA1HE1V0>A0dDKpZjYd;_Ih>zW%hjGS9R)0@mX9<3DSK4kuO_Bf07kqH@~Q|`%ckA1 zjDWJWL6Rze;Zmk)S?~RLhudR`mgTAV>!9U8})REhe-J}mM8reQM3B%rM1e>X2CTLZ|nuAl5k{a)xA z%cQ+s?ypjI@=Gl^v_oht3teOR3nK3UTvxX+HAZ9Ck^3?O1FCeh9$_=JY|ykjMm&yc z7q>U)|87tEKR0|Wa>Lj61o#qg2hHwqj=D-;qRr%0K5mR>s_PG=ay{Eqm>P3V{{!zX z05;~-gIps*W6pAr#{gG1%9G|2up~bhr{X&$PTBYo0sbioBHHz!a{w$)PXZYQl(i0$ zR5uD;meq|8-Y*jcEYWgzDlQ>IP4IQdxkiGev)y`Tuny4HExDvlQ zW!B2KIJ^&3U9Xj%t5Z`|;_G_S>VT?S_c6ySRKZ^Dg{2Cp8eG$$8eEf9gOa!>Pp7JfNT=c7NYh3>8L4?s)D!;NkzL}oT-=KX1dvbO$X#8D+c%p9{SI5V_JeE|3Yg2Ix^4iM(RN{CNV8neO_lQts*aY$=Q1+G&kFNi!a_bT;0ZX)8 zmx`wZEv*iq7y#390?2R?(sDbu9eO65~pC~08}HM3HOs_$q)y_l6cSq~|+V91=6njtjW zyO-+F`Gn})kq~w?_WYE62S6dtPmR!~zCxUzI>(_}{W(8%y~gCI>k@TqBU~jPzn81s ztMSk;wcyX4LM0!OvMa*}63re!)$Bbj++eK?{RxLVIQ$!EsW)+R$ETV} zma0%QUd7FwklNvSXsu+P=sK{I4mD`uM$#Zz)iy zPGMKf9Y*66>yS)onjPb{MIj2@Hn+7A(SOw0nE8n5y)5l-^g&pzwO{VsRQa~=@ovkr z&3nA-Nyb{h-s26t&AmK(k9S00*82hdx@g={X8eDQod(S9A^CTo2|dsV4(-&jxvxXD`IaGWM<-@w={d7qCA6UGF&g zw)+QSOZKEYJg|KoeE^{k2I;7r{@D^<$w>P0UmB;aG0EMq_?sG zJ=aE7QiQDRfcu231ims@XEHn0%*{$(6c$8SDlJ396fWCF)*nuvlH)CE?MQSorKy04;l|N5tTBlbgKUtK7caB}xb0`Mr)o&&J5JiOZf| zg)Q4eDXAUW$<~E3Q9B$W6E0P?!?Vc zb`BOYc@i-;r9CsWqvQ(NWt$m}O+R|b4DHin!6`ZFC4SE+JIeJv$}RoEjc>K(eFz(W zezy}QXOZT~K+TF~iZOQWNkQ;6^e4daEm$jxR3uUuIcUGEkZF5wL}r}Gcn^dfA-)9p zCtxS1_xJXrZnbu!+|f92cu#$}*kL{Oc|&5sY`}WzNR~{opY_x)5&8_k&rX1uKtq;j;c0JJss|20jC7-pNygtY1!7Ak+>OFyeiXcY)r@-0JcDJ|q8}T@dL~{zh#2kr#c^k2%NkH@33GW#cKgHz2RR&FJmJ zC#7=t$5ifq+e;@9G#Sa$a-i;+^LQrr?ZCM-rpuu(1ndNvtZ$dpq&zc6aRKZM!PQ=E zEQqkw1jBzb^(;iE0+y_Z@X5;a9qFI5H%5AttcZ=Pr>rT${rws5(vtN{yT7%4R5|wd zmirs9u@-Rd?;kAp!;@mczu`Ie_g^6Qm%y6`nENG>*&xDF?tkv?us=j}4`A*`#Q(V8 zG17Cm`yXnF_oIx>-u>2=2-WQZX4us%LtD`+|C=zde5>W=r|~gkk<;Nd_Nt!exp<7uVOOq%)e%n>NS{N4%qo# zS+CbstPZ2u)(mv-(gIDDHV;}0eI<~kmhr1s%O;;Zn%i5&1JP=&<3U6o0IYSq5ArUM zBPnYgN1Q@A0oFPi`h>-T2+Q+s(mHxbqi&IBAU*{!;zf|Bf&Xb8ts`BBwvJ;0&sXc< z1}}1a7Aq_hu%JBV#_z%~@<7?M*ags2RRn!|dj$$`-50q(@`4gFW`|{Q_!c3q0Cres zRZy&3kR4;+C+izn4nAc$Xdm9pdfIY0==cG{T-Jl8Ai2^%jst;A82u7CcKJ98(94cB@1XuS~5foTHUVXCi zvB9P4RMyw}AXPNiR4JNkebKDZHiV09mF!(+@cKoaL%30Hy7qJNpl=Agi8S8;tO)Im z%+;oEZ!mHnv9jivl2BRU+?dl%Zn&B-*F=M^@2Q_2l3OxDhJv8X{n1m5=0>XS96qg) zHRR}NbZUDrvm0=o+K~QAU7OQlK}#Uf$44Jbh72Skxt$f?@esMg&polK2#)FRrA|?{ zb=_Wq&kTF53yA*ucRk@);}JE;+LVD@OlNdhrPi`t&k|R zGq?hKwNtWon^_zjDSa&`(2vy~P(yBqYhV;SMxNIm(0dIl4h5Rd)gCZ$lW={or1k(i z4a^Fu_P}gKYVdvn{vcOiEvxaOOzrM9=?C~4UrJl|foW~s=NSLy+7etLK~`NC(c;Tq zXb-C`@3^MowXG7b?F{omqgCy;ODtZ?->_f1xwEEOrt`gdzqGaHvt$k3jghRM8)`!2 zr0O4=ma0EVx`URd@LZ#IZUYga4&-r?xkF6S(w{q7mKzM^QoDxrH4R1zuW5PV@+GgX z(>61oE!D$a(dkGJ>ja}RP|Uk?(875D71{_ z*>z@Jch8wWGsvvx)__ZODpY2Dx0X^mig{6H14jfct23p^eBEV;9&=eqX1;zx>R|KC z*KNJ9z&w8aLV03eCCYq#<8LI(4mQtxeY^M>6NAi3^C@Ev)_1wu#!=;&yHZD$XYO)G zl`p{4H|?zR20Po~!rQK5%!d7rubO{h?Jo0S=b9F+?bO!Hhr8{hB&~chAMU3T&K*yr zht12}@pC|znKLlA<D+TsdVN4{yA#sTfUPez)W_lU7-N&t= zp3BrC?|f%ck0R-|m1DgobR?77TPAJe)ph;0yFW5XXS3DSnqg-9R;mNH;?9jg&9ho5 zRzGD^t#M3^0GCbe$4l!S&>Mm7!&EjMEGHU`=UxmbnLte~w?jJnL-q!Ot~b_U!DUl! zMZ%TOW_bFA8(%ukPfCh5^%MR##P0xV>P)$!P2*(k_zCQ;0P0T&if;DDH?3V#e+uL+ zR>|4Z#9^R8(XG}J;_E7xG}dO~qT8&*Sg_`NUpDR*-QL9Q+ugRbyV`Qm9ag^EQN0al ztS!Jrcjh<8WPIJhC0WP4$&SXP^O#p8-X`?%S_jFpa0DUsCbIkrs^uT47go>B^fTKS-q6pU$U-{+}oQuP!E|?0o&!b2ILaJcKI#yap?JX(;4~CEqy@n z`;yl#zr++47XYlRyn}r3F*1V+Viet-Rrgq|+(<}kgpLHlbybM0|C0MFeH>ojmz7_W zamCRwnZuADsyIau^Fii`(1#^AfoueVWEA_ww_U@YEmzcKRC=`ty^AaNWc5Ssu{w1o zwEp2;qQ4^*iH*M5Xn(>agw#K{w!fOtN*}8I(Tja3HyVk9p0EAUH>CLLRd68@Rcvh# z+~z~w{!oQRHSOUGdD81c-CIwW5<1%#sWkuaKboVerk<)UO*-wZe0CexwtEfQo!!pM z$mh2_U+)Et^n6>JwuhDOe2~3fMmwX<^)hY=dIcJy>ZU&MS|92>*D^M54=&@AiazJ{ z9?pGU<|2yfea}}ur@bbR=}h~xG|_br!*kJ+-2I`es+wTy7jE3vH|oZg^wTsYK9#*J zlpP~b(ULI@i8cz(P@wLVnXu+*Y~2ib3s8Ujq)9>1($w)=joa{AYtaSuwKUDSiA(EG znMqf-%=dgRF74iyo5rH$)_MI*{2u|nYFTulaZZ}X7z31?1;_gRTcK_SvSv}YrpLU~ z!In4Ba!KBc$5Y|1CFDg!o(F1Osw%jQ%hym}0z4U9&LKBGCX0%Sc}=cP$PQN!Qgjyk z{eW-*#0-#WB4$AB26-FEe4#R}AQ_B%lXkQ+mYgmP{~{CqUdIRAF5Gz5J0l`eg+AG-$V#!*PtEF%%HK&ftl|YqxI!dUV?lmvA zNtZ>nda4)FyJ=TDp~Si^OQW}RB(^FuNN)5=(K)hdJx(1jUT#~;$XWJ66H+-pH+%y< zHkU1$KSaZGPM5L-dMBDEJ*qMH$gUse&i1pO zXj^``@iJrwXv8OYgb0?y8fI$jFMFUqk^Yk#R-?1bHIe_AM6Pbjv;Q;2X2o&lOxgdj z*=OUKdEmd56d})NrMBV?zv3@Y+8~QNmF(Y(-=${=x|JGLJv1_Z=B)Wac6Mm5p7UIp zX;dH$c55F5N6LEF*5q;ap4<(}Fn&yo?H6urKA6tLeA_ch-akv_cmk-ayVC4Evos;7 zGm|}EK+Toh>}Kydzk;|^p(g;1&6N)t$T22AOI;d1^l8}S(@<5x{|0r#K7mk7~ZSA}eBirHDzD%Azz~^Mm z*{oy&X00L@SC~bFw+%7`a zUIBR-NKXC#u@(vOeB|)7eV6P$&|CW!ec#A{tQFB`6#{0hFUavga={;2i(mBaA+;nD zVq4(h*1k_}j;x)9zNs=GYimHR5TUef1^FA0T>VGZ4llP&UWm!t;nsdi)*0l}_8$6n z%Ydu}=dxi?gse4#XaXd+{GqjUxg{!n?LU*K-B7G%qTpd+d+W?gf<)9nikM=Z>_wvI z>_MWbx1gS4-v5L~)lPA*{-4mnRpQ=%NT?=YQ6*B`*AEF@Md~?J|jBG*RbT zHii|5?8@A*7F}b3`B~XpeirD3!R*RY)l=IVOLpZ{_0U0CZ&qWnx8{cWW`K*awXb5> zYF+kLyWcIaK7H$S#mJZ$WIt&4*9|&rynD!QPrEhPN-NKPto~-aAOp)-VadKLH*=1t zAlT;qn3pQ?E(7m6P6x&ONJf1F)YT^?vhT9f6Z_8L^%tO~z9^A>*EE^E5PB(4U++X_ z|0T*)`@+UZZ-tMtPb9+K$%CZDzOeB)F&+bW^Y0AiKVFVJn1tM4lO;G~a{okTujCSQ zy^KnsAHk_y*28w%0)KpDCDNqSOsXoSCt!(S#}pc{1*Ghiw#eJ=yjai_=zeAr&8w{9Zic=YXtje$;W`v|pR1aD zsqH5Gk$~@kELnW<9A}@Jp}EnOS<_&KZ*XZapNTaPz6fy~NN*rVQq?|yQ*FO4-|6xz zmw3i#PX9+@G7!&$xB}!dpjv&1YE8Ms+j4mT*8P&{2JtJ%FCzLt^j*L}1;mF!TnTcy zh%pemLEaWI8KUt*_F4n+*$`)gOcilH#5Rz>iMR-&?jm;G0r7PZ3qj5ku@T}0kY`0~ zhA2EAF(AGbVj{>m5j!9r1i4SdD-d-SbGrq^--Vb2G9G9YoWjis8M0y+DNI6C%i|I> z>dLjGDc>9v|7h|18~+m`?|}b+_@6^m`+-Z)Xe6Oqngzj5@lTQbB$J=bbs4K>AB#Uv z{AI?!oa?w2>@pR9o%kD#-;is&GS=9K!)h#kYvXU`x&wYI@$VIXoAICJI=dySed50) z{#(Z1%e91+xl_geRQvW4PpS2^!Vqx~vr+VHdxV_+`fL$h95)^{wJ} z6Tgq~E4c23|Csor#2;t;>0H+`!+%r!bHrb4{MB45=x_fe{uSbHF#c`gb7LMK0qZXD zw;F#3*Jbpq4a9#={7U1$&vg^?;d1dm68}r%ALP1&1~N$e-^9;6Rp~0=TEdOVMDgoE zRBLMdc3d}g3WD>+?<9V2;}7PV*M-lZi9byI(~Lir>o|IdyTzX&{sQB#c9BY#Gh;YWnA0!q5g}%O8m9P-^jJ1FZEyio5jD!_}jQH>qq?;|8enOH2zy$H=RKJ z7ymu+KQaCR@%vN%#s5+KV64)W!?kh%^?wwsS`gJ58ox}}LDYZo+lb%Q_QU z4-kK(@yBs(cOvy){K?|aHvVF+y@yc$#a}M|<;LH@wSt?%%f$ba_?wNtmFsNA_FKh& zMEqxsU&(b7PX-Yt|w9d#qTSAh4D|*^)jV9L__H0rtd}m2e$5mijM#Gx6IQzbDsar&IsMKUVy~#vd*I8PtD`Mq|aFYW%t4kE8yJzfk;@ z#$PM`c=asqT$2(>u5prUW+PeFn?5DGLvHvH7Wn>S zc83na3N~ObyF=f7;2GnC?D86#Q)Em4t83Uquu{XA3YE7ujCF?c&W16WEbna?)6epO zhD`+zC zfp&0cdzo{7&2KMzJv?6qotN|5%VJ;8mr3XI{PwarRQzHMycu(e-#KY=%x*jy6l)N) zurBE^hX%zOm@TYpI?SO#u?Ara>y{34Xi%(y*uuJ}!yFnEYcRI39_cWL2E`h9Ev#oc z%%MTC244$1IvwWFpjZR2h4o5@IW#ENAZ%gBq{AE<6l);1u-@q~hX%zOj4kZgbeKbf zVhzX^c3e8lp+T_*WeYn#9p=!WSOc?#aT2ELq{_jeL9qsB3+tN>b7)Yk0ouY&NQXHz zDApitVg1u#4h@PmP+Qo5beKbfVhz?7HZUFL(4bfYwuKE!hdDGT)}U=+oah;)!J$F1 z25t*GF&*a6pjd;qg$+rEIW#EN0B&JJ(_sz`iZzH^SVcO_p+T_*atj-l4s&QwtijyE zhNr_E%BFY5Knoj@4s&QwtU=wvMyA6Y8Wd|_x3E#^Foy=k8r&`Hq;!}=gJKQv7B)H^ z=Fp&6gS>^Ek`8ldP^^L8!p5Y-92yjBu(z;N(_sz`iZ$R{*lFo7hX%zO^et>`I?SO# zu?Bt%J3Srd(4bg@zlEKV4s&QwtOC8VKdWV z4h@Pmaj>vi=`e=|#hN@=*z9zeLxW;XAS~>hbeKbfVof3}?A&yiLxW;XBrI%BI?SO# zu_hB1Ha8vS(4bfo3JaT;4s&QwtVxB1otF-CXi%()g@w&ehdGqJS{mOLr1=ijI+(ht zhM6_EmbK9uN;96V@G_iR+iKQBiw8m3cid;@Uy>U(o}i~LpyhfbnmZnBplyHB=biH} znQYslw39FYl5-wqqS4?p^yXh$Tk#q+<)$wGGJ8szF($~r+--Y$O{%Z71(XJx^1#

    !sW!fNZBhs6zEkJvr`i3OE@F4{ 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 Date: Mon, 17 Oct 2022 13:29:53 +0200 Subject: [PATCH 152/155] add ability to remove root logging appender --- src/main/java/com/sparrowwallet/drongo/Drongo.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/main/java/com/sparrowwallet/drongo/Drongo.java b/src/main/java/com/sparrowwallet/drongo/Drongo.java index 24eb887..58bc521 100644 --- a/src/main/java/com/sparrowwallet/drongo/Drongo.java +++ b/src/main/java/com/sparrowwallet/drongo/Drongo.java @@ -83,6 +83,11 @@ public class Drongo { root.setLevel(ch.qos.logback.classic.Level.toLevel(level.toString())); } + public static void removeRootLogAppender(String appenderName) { + ch.qos.logback.classic.Logger root = (ch.qos.logback.classic.Logger)LoggerFactory.getLogger(org.slf4j.Logger.ROOT_LOGGER_NAME); + root.detachAppender(appenderName); + } + public static Provider getProvider() { return new BouncyCastleProvider(); } From fa18ec9d458bb17221fb01b6be9f4eceb354a156 Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Mon, 14 Nov 2022 10:59:33 +0200 Subject: [PATCH 153/155] add walletconfig --- .../sparrowwallet/drongo/wallet/Wallet.java | 22 ++++++++++ .../drongo/wallet/WalletConfig.java | 41 +++++++++++++++++++ 2 files changed, 63 insertions(+) create mode 100644 src/main/java/com/sparrowwallet/drongo/wallet/WalletConfig.java diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java index 1aa0129..ac26736 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java @@ -38,6 +38,7 @@ public class Wallet extends Persistable implements Comparable { private final TreeSet purposeNodes = new TreeSet<>(); private final Map transactions = new HashMap<>(); private final Map detachedLabels = new HashMap<>(); + private WalletConfig walletConfig; private MixConfig mixConfig; private final Map utxoMixes = new HashMap<>(); private Integer storedBlockHeight; @@ -441,6 +442,26 @@ public class Wallet extends Persistable implements Comparable { return detachedLabels; } + public WalletConfig getWalletConfig() { + return walletConfig; + } + + public WalletConfig getMasterWalletConfig() { + if(!isMasterWallet()) { + return getMasterWallet().getMasterWalletConfig(); + } + + if(walletConfig == null) { + walletConfig = new WalletConfig(); + } + + return walletConfig; + } + + public void setWalletConfig(WalletConfig walletConfig) { + this.walletConfig = walletConfig; + } + public MixConfig getMixConfig() { return mixConfig; } @@ -1805,6 +1826,7 @@ public class Wallet extends Persistable implements Comparable { for(String entry : detachedLabels.keySet()) { copy.detachedLabels.put(entry, detachedLabels.get(entry)); } + copy.setWalletConfig(walletConfig == null ? null : walletConfig.copy()); copy.setMixConfig(mixConfig == null ? null : mixConfig.copy()); for(Sha256Hash hash : utxoMixes.keySet()) { copy.utxoMixes.put(hash, utxoMixes.get(hash)); diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/WalletConfig.java b/src/main/java/com/sparrowwallet/drongo/wallet/WalletConfig.java new file mode 100644 index 0000000..11e58fb --- /dev/null +++ b/src/main/java/com/sparrowwallet/drongo/wallet/WalletConfig.java @@ -0,0 +1,41 @@ +package com.sparrowwallet.drongo.wallet; + +public class WalletConfig extends Persistable { + private byte[] iconData; + private boolean userIcon; + private boolean usePayNym; + + public WalletConfig() { + } + + public WalletConfig(byte[] iconData, boolean userIcon, boolean usePayNym) { + this.iconData = iconData; + this.userIcon = userIcon; + this.usePayNym = usePayNym; + } + + public byte[] getIconData() { + return iconData; + } + + public boolean isUserIcon() { + return userIcon; + } + + public void setIconData(byte[] iconData, boolean userIcon) { + this.iconData = iconData; + this.userIcon = userIcon; + } + + public boolean isUsePayNym() { + return usePayNym; + } + + public void setUsePayNym(boolean usePayNym) { + this.usePayNym = usePayNym; + } + + public WalletConfig copy() { + return new WalletConfig(iconData, userIcon, usePayNym); + } +} From 692f23e02656b43b58c33b44467f920ddc3a3f65 Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Thu, 8 Dec 2022 08:40:49 +0200 Subject: [PATCH 154/155] add block header serialization and output descriptor normalize functions --- .../drongo/OutputDescriptor.java | 15 ++++++++ .../drongo/protocol/BlockHeader.java | 36 +++++++++++++++++++ 2 files changed, 51 insertions(+) diff --git a/src/main/java/com/sparrowwallet/drongo/OutputDescriptor.java b/src/main/java/com/sparrowwallet/drongo/OutputDescriptor.java index 154bae2..c5d17d7 100644 --- a/src/main/java/com/sparrowwallet/drongo/OutputDescriptor.java +++ b/src/main/java/com/sparrowwallet/drongo/OutputDescriptor.java @@ -275,6 +275,10 @@ public class OutputDescriptor { return wallet; } + public static String toDescriptorString(Address address) { + return "addr(" + address + ")"; + } + public static OutputDescriptor getOutputDescriptor(Wallet wallet) { return getOutputDescriptor(wallet, null); } @@ -392,6 +396,17 @@ public class OutputDescriptor { return new OutputDescriptor(scriptType, multisigThreshold, keyDerivationMap, keyChildDerivationMap); } + public static String normalize(String descriptor) { + String normalized = descriptor.replaceAll("'", "h"); + + int checksumHash = normalized.lastIndexOf('#'); + if(checksumHash > -1) { + normalized = normalized.substring(0, checksumHash); + } + + return normalized + "#" + getChecksum(normalized); + } + private static String getChecksum(String descriptor) { BigInteger c = BigInteger.valueOf(1); int cls = 0; diff --git a/src/main/java/com/sparrowwallet/drongo/protocol/BlockHeader.java b/src/main/java/com/sparrowwallet/drongo/protocol/BlockHeader.java index f152876..863d3cb 100644 --- a/src/main/java/com/sparrowwallet/drongo/protocol/BlockHeader.java +++ b/src/main/java/com/sparrowwallet/drongo/protocol/BlockHeader.java @@ -1,7 +1,12 @@ package com.sparrowwallet.drongo.protocol; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.OutputStream; import java.util.Date; +import static com.sparrowwallet.drongo.Utils.uint32ToByteStreamLE; + public class BlockHeader extends Message { private long version; private Sha256Hash prevBlockHash; @@ -14,6 +19,16 @@ public class BlockHeader extends Message { super(rawheader, 0); } + public BlockHeader(long version, Sha256Hash prevBlockHash, Sha256Hash merkleRoot, Sha256Hash witnessRoot, long time, long difficultyTarget, long nonce) { + this.version = version; + this.prevBlockHash = prevBlockHash; + this.merkleRoot = merkleRoot; + this.witnessRoot = witnessRoot; + this.time = time; + this.difficultyTarget = difficultyTarget; + this.nonce = nonce; + } + @Override protected void parse() throws ProtocolException { version = readUint32(); @@ -57,4 +72,25 @@ public class BlockHeader extends Message { public long getNonce() { return nonce; } + + public byte[] bitcoinSerialize() { + try { + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + bitcoinSerializeToStream(outputStream); + return outputStream.toByteArray(); + } catch (IOException e) { + //can't happen + } + + return null; + } + + protected void bitcoinSerializeToStream(OutputStream stream) throws IOException { + uint32ToByteStreamLE(version, stream); + stream.write(prevBlockHash.getReversedBytes()); + stream.write(merkleRoot.getReversedBytes()); + uint32ToByteStreamLE(time, stream); + uint32ToByteStreamLE(difficultyTarget, stream); + uint32ToByteStreamLE(nonce, stream); + } } From ca98d4d9b60c5a53e758fa90dcbe1c0dff78fcb6 Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Thu, 15 Dec 2022 08:28:16 +0200 Subject: [PATCH 155/155] add minimal wallet copy functionality --- .../sparrowwallet/drongo/wallet/Wallet.java | 30 +++++++++++-------- 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java index ac26736..5e13524 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java @@ -1802,12 +1802,16 @@ public class Wallet extends Persistable implements Comparable { } public Wallet copy() { + return copy(true); + } + + public Wallet copy(boolean includeHistory) { Wallet copy = new Wallet(name); copy.setId(getId()); copy.setLabel(label); copy.setMasterWallet(masterWallet); for(Wallet childWallet : childWallets) { - Wallet copyChildWallet = childWallet.copy(); + Wallet copyChildWallet = childWallet.copy(includeHistory); copyChildWallet.setMasterWallet(copy); copy.childWallets.add(copyChildWallet); } @@ -1817,20 +1821,22 @@ public class Wallet extends Persistable implements Comparable { for(Keystore keystore : keystores) { copy.getKeystores().add(keystore.copy()); } - for(WalletNode node : purposeNodes) { - copy.purposeNodes.add(node.copy(copy)); - } - for(Sha256Hash hash : transactions.keySet()) { - copy.transactions.put(hash, transactions.get(hash)); - } - for(String entry : detachedLabels.keySet()) { - copy.detachedLabels.put(entry, detachedLabels.get(entry)); + if(includeHistory) { + for(WalletNode node : purposeNodes) { + copy.purposeNodes.add(node.copy(copy)); + } + for(Sha256Hash hash : transactions.keySet()) { + copy.transactions.put(hash, transactions.get(hash)); + } + for(String entry : detachedLabels.keySet()) { + copy.detachedLabels.put(entry, detachedLabels.get(entry)); + } + for(Sha256Hash hash : utxoMixes.keySet()) { + copy.utxoMixes.put(hash, utxoMixes.get(hash)); + } } copy.setWalletConfig(walletConfig == null ? null : walletConfig.copy()); copy.setMixConfig(mixConfig == null ? null : mixConfig.copy()); - for(Sha256Hash hash : utxoMixes.keySet()) { - copy.utxoMixes.put(hash, utxoMixes.get(hash)); - } copy.setStoredBlockHeight(getStoredBlockHeight()); copy.gapLimit = gapLimit; copy.watchLast = watchLast;

    gaQX4dH0{<#Inz%t-wm#=yZSon@g8XZo#`UZ- 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

    - * {@inheritDoc} - */ - @SuppressWarnings("deprecation") - @Override - public void finalize() throws Throwable { - clear(); - super.finalize(); - } - /** * Randomly pad the characters to not store the real character in memory. * From b2f5f5ffebfc0ce9f0d992f3ac3b59965661491b Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Thu, 21 Jul 2022 12:29:21 +0200 Subject: [PATCH 141/155] spend change from notification transactions only if necessary --- .../drongo/bip47/PaymentCode.java | 4 ++++ .../drongo/wallet/OutputGroup.java | 16 +++++++++---- .../sparrowwallet/drongo/wallet/Wallet.java | 23 +++++++++++++++---- 3 files changed, 35 insertions(+), 8 deletions(-) diff --git a/src/main/java/com/sparrowwallet/drongo/bip47/PaymentCode.java b/src/main/java/com/sparrowwallet/drongo/bip47/PaymentCode.java index c2a2966..ecdf87e 100644 --- a/src/main/java/com/sparrowwallet/drongo/bip47/PaymentCode.java +++ b/src/main/java/com/sparrowwallet/drongo/bip47/PaymentCode.java @@ -174,6 +174,10 @@ public class PaymentCode { if(scriptChunks.get(1).getData() != null && scriptChunks.get(1).getData().length != 80) { return null; } + byte[] data = scriptChunks.get(1).getData(); + if(data[0] != 0x01 || (data[2] != 0x02 && data[2] != 0x03)) { + return null; + } return scriptChunks; } diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/OutputGroup.java b/src/main/java/com/sparrowwallet/drongo/wallet/OutputGroup.java index b66e928..59b703c 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/OutputGroup.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/OutputGroup.java @@ -20,6 +20,7 @@ public class OutputGroup { private long longTermFee = 0; private int depth = Integer.MAX_VALUE; private boolean allInputsFromWallet = true; + private boolean spendLast; public OutputGroup(ScriptType scriptType, int walletBlockHeight, long inputWeightUnits, double feeRate, double longTermFeeRate) { this.scriptType = scriptType; @@ -29,7 +30,7 @@ public class OutputGroup { this.longTermFeeRate = longTermFeeRate; } - public void add(BlockTransactionHashIndex utxo, boolean allInputsFromWallet) { + public void add(BlockTransactionHashIndex utxo, boolean allInputsFromWallet, boolean spendLast) { utxos.add(utxo); value += utxo.getValue(); effectiveValue += utxo.getValue() - (long)(inputWeightUnits * feeRate / WITNESS_SCALE_FACTOR); @@ -37,6 +38,7 @@ public class OutputGroup { longTermFee += (long)(inputWeightUnits * longTermFeeRate / WITNESS_SCALE_FACTOR); depth = utxo.getHeight() <= 0 ? 0 : Math.min(depth, walletBlockHeight - utxo.getHeight() + 1); this.allInputsFromWallet &= allInputsFromWallet; + this.spendLast |= spendLast; } public void remove(BlockTransactionHashIndex utxo) { @@ -80,21 +82,27 @@ public class OutputGroup { return allInputsFromWallet; } + public boolean isSpendLast() { + return spendLast; + } + public static class Filter { private final int minWalletConfirmations; private final int minExternalConfirmations; + private final boolean includeSpendLast; - public Filter(int minWalletConfirmations, int minExternalConfirmations) { + public Filter(int minWalletConfirmations, int minExternalConfirmations, boolean includeSpendLast) { this.minWalletConfirmations = minWalletConfirmations; this.minExternalConfirmations = minExternalConfirmations; + this.includeSpendLast = includeSpendLast; } public boolean isEligible(OutputGroup outputGroup) { if(outputGroup.isAllInputsFromWallet()) { - return outputGroup.getDepth() >= minWalletConfirmations; + return outputGroup.getDepth() >= minWalletConfirmations && (includeSpendLast || !outputGroup.isSpendLast()); } - return outputGroup.getDepth() >= minExternalConfirmations; + return outputGroup.getDepth() >= minExternalConfirmations && (includeSpendLast || !outputGroup.isSpendLast()); } } } diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java index d69755f..76eff7e 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java @@ -1163,10 +1163,13 @@ public class Wallet extends Persistable implements Comparable { List utxoPool = getGroupedUtxos(utxoFilters, feeRate, longTermFeeRate, groupByAddress, includeSpentMempoolOutputs); List filters = new ArrayList<>(); - filters.add(new OutputGroup.Filter(1, 6)); - filters.add(new OutputGroup.Filter(1, 1)); + filters.add(new OutputGroup.Filter(1, 6, false)); + filters.add(new OutputGroup.Filter(1, 1, false)); if(includeMempoolOutputs) { - filters.add(new OutputGroup.Filter(0, 0)); + filters.add(new OutputGroup.Filter(0, 0, false)); + filters.add(new OutputGroup.Filter(0, 0, true)); + } else { + filters.add(new OutputGroup.Filter(1, 1, true)); } if(sendMax) { @@ -1237,7 +1240,7 @@ public class Wallet extends Persistable implements Comparable { outputGroups.add(outputGroup); } - outputGroup.add(utxo, allInputsFromWallet(walletTransactions, walletTxos, utxo.getHash())); + outputGroup.add(utxo, allInputsFromWallet(walletTransactions, walletTxos, utxo.getHash()), isNotificationChange(walletTransactions, utxo.getHash())); } } } @@ -1280,6 +1283,18 @@ public class Wallet extends Persistable implements Comparable { return true; } + private boolean isNotificationChange(Map walletTransactions, Sha256Hash txId) { + BlockTransaction utxoBlkTx = walletTransactions.get(txId); + try { + PaymentCode.getOpReturnData(utxoBlkTx.getTransaction()); + return true; + } catch(IllegalArgumentException e) { + //ignore, not a notification tx + } + + return false; + } + /** * Determines the maximum total amount this wallet can send for the number and type of addresses at the given fee rate * From ce90e29284a3faa4479620a612a05b444b2a56b1 Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Mon, 25 Jul 2022 13:36:38 +0200 Subject: [PATCH 142/155] allow psbts without previous utxo data --- .../com/sparrowwallet/drongo/psbt/PSBT.java | 26 +++++++++---------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/src/main/java/com/sparrowwallet/drongo/psbt/PSBT.java b/src/main/java/com/sparrowwallet/drongo/psbt/PSBT.java index a16ed47..cf79731 100644 --- a/src/main/java/com/sparrowwallet/drongo/psbt/PSBT.java +++ b/src/main/java/com/sparrowwallet/drongo/psbt/PSBT.java @@ -341,12 +341,7 @@ public class PSBT { } if(verifySignatures) { - for(PSBTInput input : psbtInputs) { - boolean verified = input.verifySignatures(); - if(!verified && input.getPartialSignatures().size() > 0) { - throw new PSBTSignatureException("Unverifiable partial signatures provided"); - } - } + verifySignatures(psbtInputs); } } @@ -382,7 +377,7 @@ public class PSBT { if(utxo != null) { fee += utxo.getValue(); } else { - log.error("Cannot determine fee - not enough information provided on inputs"); + log.warn("Cannot determine fee - inputs are missing UTXO data"); return null; } } @@ -396,14 +391,17 @@ public class PSBT { } public void verifySignatures() throws PSBTSignatureException { - for(PSBTInput input : getPsbtInputs()) { - boolean verified = input.verifySignatures(); - if(!verified) { - if(input.getPartialSignatures().size() > 0) { - throw new PSBTSignatureException("Unverifiable partial signatures provided"); - } + verifySignatures(getPsbtInputs()); + } - throw new PSBTSignatureException("No UTXO data provided"); + private void verifySignatures(List psbtInputs) throws PSBTSignatureException { + for(PSBTInput input : psbtInputs) { + boolean verified = input.verifySignatures(); + if(!verified && input.getPartialSignatures().size() > 0) { + throw new PSBTSignatureException("Unverifiable partial signatures provided"); + } + if(!verified && input.isTaproot() && input.getTapKeyPathSignature() != null) { + throw new PSBTSignatureException("Unverifiable taproot keypath signature provided"); } } } From 8a6d2da5c911b3f63426c9e5331c55a36c27befc Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Mon, 25 Jul 2022 14:46:54 +0200 Subject: [PATCH 143/155] disallow duplicate xpubs in multisig wallet keystores --- .../java/com/sparrowwallet/drongo/wallet/Wallet.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java index 76eff7e..fe48d3e 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java @@ -1710,6 +1710,10 @@ public class Wallet extends Persistable implements Comparable { throw new InvalidWalletException("Keystore " + keystore.getLabel() + " derivation of " + keystore.getKeyDerivation().getDerivationPath() + " in " + scriptType.getName() + " wallet matches another default script type."); } } + + if(containsDuplicateExtendedKeys()) { + throw new InvalidWalletException("Wallet keystores have duplicate extended public keys"); + } } public boolean derivationMatchesAnotherScriptType(String derivationPath) { @@ -1732,6 +1736,14 @@ public class Wallet extends Persistable implements Comparable { return !keystores.stream().map(Keystore::getLabel).allMatch(new HashSet<>()::add); } + public boolean containsDuplicateExtendedKeys() { + if(keystores.size() <= 1) { + return false; + } + + return !keystores.stream().map(Keystore::getExtendedPublicKey).allMatch(new HashSet<>()::add); + } + public void makeLabelsUnique(Keystore newKeystore) { makeLabelsUnique(newKeystore, false); } From ca833fbf6807e9db30135562000329b7423b9fb7 Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Fri, 29 Jul 2022 09:44:57 +0200 Subject: [PATCH 144/155] use locale-insensitive lowercase and uppercase functions --- .../com/sparrowwallet/drongo/KeyDerivation.java | 3 ++- src/main/java/com/sparrowwallet/drongo/Network.java | 4 +++- .../com/sparrowwallet/drongo/PropertyDefiner.java | 10 ++++++---- .../com/sparrowwallet/drongo/address/Address.java | 3 ++- .../sparrowwallet/drongo/protocol/ScriptType.java | 2 +- .../com/sparrowwallet/drongo/uri/BitcoinURI.java | 2 +- .../sparrowwallet/drongo/wallet/WalletModel.java | 8 +++++--- .../drongo/protocol/TransactionTest.java | 5 +++-- .../sparrowwallet/drongo/uri/BitcoinUriTest.java | 4 +++- .../com/sparrowwallet/drongo/wallet/PolicyTest.java | 13 +++++++------ 10 files changed, 33 insertions(+), 21 deletions(-) diff --git a/src/main/java/com/sparrowwallet/drongo/KeyDerivation.java b/src/main/java/com/sparrowwallet/drongo/KeyDerivation.java index 3d6020b..123f046 100644 --- a/src/main/java/com/sparrowwallet/drongo/KeyDerivation.java +++ b/src/main/java/com/sparrowwallet/drongo/KeyDerivation.java @@ -5,6 +5,7 @@ import com.sparrowwallet.drongo.crypto.ChildNumber; import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.Locale; public class KeyDerivation { private final String masterFingerprint; @@ -16,7 +17,7 @@ public class KeyDerivation { } public KeyDerivation(String masterFingerprint, String derivationPath) { - this.masterFingerprint = masterFingerprint == null ? null : masterFingerprint.toLowerCase(); + this.masterFingerprint = masterFingerprint == null ? null : masterFingerprint.toLowerCase(Locale.ROOT); this.derivationPath = derivationPath; this.derivation = parsePath(derivationPath); } diff --git a/src/main/java/com/sparrowwallet/drongo/Network.java b/src/main/java/com/sparrowwallet/drongo/Network.java index 4175ac5..a20fa34 100644 --- a/src/main/java/com/sparrowwallet/drongo/Network.java +++ b/src/main/java/com/sparrowwallet/drongo/Network.java @@ -1,5 +1,7 @@ package com.sparrowwallet.drongo; +import java.util.Locale; + public enum Network { MAINNET("mainnet", 0, "1", 5, "3", "bc", ExtendedKey.Header.xprv, ExtendedKey.Header.xpub, 128, 8332), TESTNET("testnet", 111, "mn", 196, "2", "tb", ExtendedKey.Header.tprv, ExtendedKey.Header.tpub, 239, 18332), @@ -39,7 +41,7 @@ public enum Network { } public String toDisplayString() { - return name.substring(0, 1).toUpperCase() + name.substring(1); + return name.substring(0, 1).toUpperCase(Locale.ROOT) + name.substring(1); } public int getP2PKHAddressHeader() { diff --git a/src/main/java/com/sparrowwallet/drongo/PropertyDefiner.java b/src/main/java/com/sparrowwallet/drongo/PropertyDefiner.java index 7f36c21..e994663 100644 --- a/src/main/java/com/sparrowwallet/drongo/PropertyDefiner.java +++ b/src/main/java/com/sparrowwallet/drongo/PropertyDefiner.java @@ -2,6 +2,8 @@ package com.sparrowwallet.drongo; import ch.qos.logback.core.PropertyDefinerBase; +import java.util.Locale; + public class PropertyDefiner extends PropertyDefinerBase { private String application; @@ -11,15 +13,15 @@ public class PropertyDefiner extends PropertyDefinerBase { @Override public String getPropertyValue() { - if(System.getProperty(application.toLowerCase() + ".home") != null) { - return System.getProperty(application.toLowerCase() + ".home"); + if(System.getProperty(application.toLowerCase(Locale.ROOT) + ".home") != null) { + return System.getProperty(application.toLowerCase(Locale.ROOT) + ".home"); } - return isWindows() ? System.getenv("APPDATA") + "/" + application.substring(0, 1).toUpperCase() + application.substring(1).toLowerCase() : System.getProperty("user.home") + "/." + application.toLowerCase(); + return isWindows() ? System.getenv("APPDATA") + "/" + application.substring(0, 1).toUpperCase(Locale.ROOT) + application.substring(1).toLowerCase(Locale.ROOT) : System.getProperty("user.home") + "/." + application.toLowerCase(Locale.ROOT); } private boolean isWindows() { String osName = System.getProperty("os.name"); - return (osName != null && osName.toLowerCase().startsWith("windows")); + return (osName != null && osName.toLowerCase(Locale.ROOT).startsWith("windows")); } } diff --git a/src/main/java/com/sparrowwallet/drongo/address/Address.java b/src/main/java/com/sparrowwallet/drongo/address/Address.java index af55c62..fc9bb0d 100644 --- a/src/main/java/com/sparrowwallet/drongo/address/Address.java +++ b/src/main/java/com/sparrowwallet/drongo/address/Address.java @@ -7,6 +7,7 @@ import com.sparrowwallet.drongo.protocol.Script; import com.sparrowwallet.drongo.protocol.ScriptType; import java.util.Arrays; +import java.util.Locale; public abstract class Address { protected final byte[] data; @@ -106,7 +107,7 @@ public abstract class Address { } } - if(address.toLowerCase().startsWith(network.getBech32AddressHRP())) { + if(address.toLowerCase(Locale.ROOT).startsWith(network.getBech32AddressHRP())) { try { Bech32.Bech32Data data = Bech32.decode(address); if(data.hrp.equals(network.getBech32AddressHRP())) { diff --git a/src/main/java/com/sparrowwallet/drongo/protocol/ScriptType.java b/src/main/java/com/sparrowwallet/drongo/protocol/ScriptType.java index ecbec90..f79cd7b 100644 --- a/src/main/java/com/sparrowwallet/drongo/protocol/ScriptType.java +++ b/src/main/java/com/sparrowwallet/drongo/protocol/ScriptType.java @@ -1288,7 +1288,7 @@ public enum ScriptType { scriptTypes.sort((o1, o2) -> o2.getDescriptor().length() - o1.getDescriptor().length()); for(ScriptType scriptType : scriptTypes) { - if(descriptor.toLowerCase().startsWith(scriptType.getDescriptor())) { + if(descriptor.toLowerCase(Locale.ROOT).startsWith(scriptType.getDescriptor())) { return scriptType; } } diff --git a/src/main/java/com/sparrowwallet/drongo/uri/BitcoinURI.java b/src/main/java/com/sparrowwallet/drongo/uri/BitcoinURI.java index 9ab8e57..800d0b8 100644 --- a/src/main/java/com/sparrowwallet/drongo/uri/BitcoinURI.java +++ b/src/main/java/com/sparrowwallet/drongo/uri/BitcoinURI.java @@ -154,7 +154,7 @@ public class BitcoinURI { if(sepIndex == 0) { throw new BitcoinURIParseException("Malformed Bitcoin URI - empty name '" + nameValuePairToken + "'"); } - final String nameToken = nameValuePairToken.substring(0, sepIndex).toLowerCase(Locale.ENGLISH); + final String nameToken = nameValuePairToken.substring(0, sepIndex).toLowerCase(Locale.ROOT); final String valueToken = nameValuePairToken.substring(sepIndex + 1); // Parse the amount. diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/WalletModel.java b/src/main/java/com/sparrowwallet/drongo/wallet/WalletModel.java index b73e442..628958e 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/WalletModel.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/WalletModel.java @@ -1,10 +1,12 @@ package com.sparrowwallet.drongo.wallet; +import java.util.Locale; + public enum WalletModel { SEED, SPARROW, BITCOIN_CORE, ELECTRUM, TREZOR_1, TREZOR_T, COLDCARD, LEDGER_NANO_S, LEDGER_NANO_X, DIGITALBITBOX_01, KEEPKEY, SPECTER_DESKTOP, COBO_VAULT, BITBOX_02, SPECTER_DIY, PASSPORT, BLUE_WALLET, KEYSTONE, SEEDSIGNER, CARAVAN, GORDIAN_SEED_TOOL, JADE, LEDGER_NANO_S_PLUS; public static WalletModel getModel(String model) { - return valueOf(model.toUpperCase()); + return valueOf(model.toUpperCase(Locale.ROOT)); } public String getType() { @@ -44,7 +46,7 @@ public enum WalletModel { return "seedtool"; } - return this.toString().toLowerCase(); + return this.toString().toLowerCase(Locale.ROOT); } public boolean alwaysIncludeNonWitnessUtxo() { @@ -74,7 +76,7 @@ public enum WalletModel { } public String toDisplayString() { - String line = this.toString().toLowerCase(); + String line = this.toString().toLowerCase(Locale.ROOT); String[] words = line.split("_"); StringBuilder builder = new StringBuilder(); for(String word : words) { diff --git a/src/test/java/com/sparrowwallet/drongo/protocol/TransactionTest.java b/src/test/java/com/sparrowwallet/drongo/protocol/TransactionTest.java index 9934020..6bd3425 100644 --- a/src/test/java/com/sparrowwallet/drongo/protocol/TransactionTest.java +++ b/src/test/java/com/sparrowwallet/drongo/protocol/TransactionTest.java @@ -10,6 +10,7 @@ import org.junit.Test; import java.io.ByteArrayOutputStream; import java.io.IOException; +import java.util.Locale; import java.util.Map; import java.util.TreeMap; @@ -484,9 +485,9 @@ public class TransactionTest { @Test public void signBip340() { ECKey privKey = ECKey.fromPrivate(Utils.hexToBytes("0000000000000000000000000000000000000000000000000000000000000003")); - Assert.assertEquals("F9308A019258C31049344F85F89D5229B531C845836F99B08601F113BCE036F9", Utils.bytesToHex(privKey.getPubKeyXCoord()).toUpperCase()); + Assert.assertEquals("F9308A019258C31049344F85F89D5229B531C845836F99B08601F113BCE036F9", Utils.bytesToHex(privKey.getPubKeyXCoord()).toUpperCase(Locale.ROOT)); SchnorrSignature sig = privKey.signSchnorr(Sha256Hash.ZERO_HASH); - Assert.assertEquals("E907831F80848D1069A5371B402410364BDF1C5F8307B0084C55F1CE2DCA821525F66A4A85EA8B71E482A74F382D2CE5EBEEE8FDB2172F477DF4900D310536C0", Utils.bytesToHex(sig.encode()).toUpperCase()); + Assert.assertEquals("E907831F80848D1069A5371B402410364BDF1C5F8307B0084C55F1CE2DCA821525F66A4A85EA8B71E482A74F382D2CE5EBEEE8FDB2172F477DF4900D310536C0", Utils.bytesToHex(sig.encode()).toUpperCase(Locale.ROOT)); } @Test diff --git a/src/test/java/com/sparrowwallet/drongo/uri/BitcoinUriTest.java b/src/test/java/com/sparrowwallet/drongo/uri/BitcoinUriTest.java index 52c6628..8127ddf 100644 --- a/src/test/java/com/sparrowwallet/drongo/uri/BitcoinUriTest.java +++ b/src/test/java/com/sparrowwallet/drongo/uri/BitcoinUriTest.java @@ -3,13 +3,15 @@ package com.sparrowwallet.drongo.uri; import org.junit.Assert; import org.junit.Test; +import java.util.Locale; + public class BitcoinUriTest { @Test public void testSamourai() throws BitcoinURIParseException { String uri = "bitcoin:BC1QT4NRM47695YWDG9N30N68JARMXRJNKFMR36994?amount=0,001"; BitcoinURI bitcoinURI = new BitcoinURI(uri); - Assert.assertEquals("BC1QT4NRM47695YWDG9N30N68JARMXRJNKFMR36994".toLowerCase(), bitcoinURI.getAddress().toString()); + Assert.assertEquals("BC1QT4NRM47695YWDG9N30N68JARMXRJNKFMR36994".toLowerCase(Locale.ROOT), bitcoinURI.getAddress().toString()); Assert.assertEquals(Long.valueOf(100000), bitcoinURI.getAmount()); } } diff --git a/src/test/java/com/sparrowwallet/drongo/wallet/PolicyTest.java b/src/test/java/com/sparrowwallet/drongo/wallet/PolicyTest.java index 811579c..a0f985d 100644 --- a/src/test/java/com/sparrowwallet/drongo/wallet/PolicyTest.java +++ b/src/test/java/com/sparrowwallet/drongo/wallet/PolicyTest.java @@ -7,6 +7,7 @@ import org.junit.Assert; import org.junit.Test; import java.util.List; +import java.util.Locale; public class PolicyTest { @Test @@ -16,27 +17,27 @@ public class PolicyTest { Keystore keystore3 = new Keystore("Keystore 3"); Policy policy = Policy.getPolicy(PolicyType.SINGLE, ScriptType.P2PKH, List.of(keystore1), 1); - Assert.assertEquals("pkh(keystore1)", policy.getMiniscript().toString().toLowerCase()); + Assert.assertEquals("pkh(keystore1)", policy.getMiniscript().toString().toLowerCase(Locale.ROOT)); Assert.assertEquals(1, policy.getNumSignaturesRequired()); Policy policy2 = Policy.getPolicy(PolicyType.SINGLE, ScriptType.P2SH_P2WPKH, List.of(keystore1), 1); - Assert.assertEquals("sh(wpkh(keystore1))", policy2.getMiniscript().toString().toLowerCase()); + Assert.assertEquals("sh(wpkh(keystore1))", policy2.getMiniscript().toString().toLowerCase(Locale.ROOT)); Assert.assertEquals(1, policy2.getNumSignaturesRequired()); Policy policy3 = Policy.getPolicy(PolicyType.SINGLE, ScriptType.P2WPKH, List.of(keystore1), 1); - Assert.assertEquals("wpkh(keystore1)", policy3.getMiniscript().toString().toLowerCase()); + Assert.assertEquals("wpkh(keystore1)", policy3.getMiniscript().toString().toLowerCase(Locale.ROOT)); Assert.assertEquals(1, policy3.getNumSignaturesRequired()); Policy policy4 = Policy.getPolicy(PolicyType.MULTI, ScriptType.P2SH, List.of(keystore1, keystore2, keystore3), 2); - Assert.assertEquals("sh(sortedmulti(2,keystore1,keystore2,keystore3))", policy4.getMiniscript().toString().toLowerCase()); + Assert.assertEquals("sh(sortedmulti(2,keystore1,keystore2,keystore3))", policy4.getMiniscript().toString().toLowerCase(Locale.ROOT)); Assert.assertEquals(2, policy4.getNumSignaturesRequired()); Policy policy5 = Policy.getPolicy(PolicyType.MULTI, ScriptType.P2SH_P2WSH, List.of(keystore1, keystore2, keystore3), 2); - Assert.assertEquals("sh(wsh(sortedmulti(2,keystore1,keystore2,keystore3)))", policy5.getMiniscript().toString().toLowerCase()); + Assert.assertEquals("sh(wsh(sortedmulti(2,keystore1,keystore2,keystore3)))", policy5.getMiniscript().toString().toLowerCase(Locale.ROOT)); Assert.assertEquals(2, policy5.getNumSignaturesRequired()); Policy policy6 = Policy.getPolicy(PolicyType.MULTI, ScriptType.P2WSH, List.of(keystore1, keystore2, keystore3), 2); - Assert.assertEquals("wsh(sortedmulti(2,keystore1,keystore2,keystore3))", policy6.getMiniscript().toString().toLowerCase()); + Assert.assertEquals("wsh(sortedmulti(2,keystore1,keystore2,keystore3))", policy6.getMiniscript().toString().toLowerCase(Locale.ROOT)); Assert.assertEquals(2, policy6.getNumSignaturesRequired()); } } From ddaf698c1011e5b01c7c3ed1e7693145ba5531ac Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Mon, 1 Aug 2022 14:16:20 +0200 Subject: [PATCH 145/155] avoid saving address data where master wallet has a passphrase --- src/main/java/com/sparrowwallet/drongo/wallet/WalletNode.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/WalletNode.java b/src/main/java/com/sparrowwallet/drongo/wallet/WalletNode.java index d4267c2..484e5cd 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/WalletNode.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/WalletNode.java @@ -272,7 +272,8 @@ public class WalletNode extends Persistable implements Comparable { return address; } - if(wallet.getKeystores().stream().noneMatch(Keystore::needsPassphrase)) { + Wallet masterWallet = wallet.isMasterWallet() ? wallet : wallet.getMasterWallet(); + if(masterWallet.getKeystores().stream().noneMatch(Keystore::needsPassphrase)) { address = wallet.getAddress(this); return address; } From 8cdea77562643edf9d460a594178c1f44deeb248 Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Thu, 4 Aug 2022 11:13:27 +0200 Subject: [PATCH 146/155] refactor supported bip47 script type lists --- .../java/com/sparrowwallet/drongo/bip47/PaymentCode.java | 3 +++ src/main/java/com/sparrowwallet/drongo/protocol/Bech32.java | 6 +++++- src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java | 4 ++-- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/sparrowwallet/drongo/bip47/PaymentCode.java b/src/main/java/com/sparrowwallet/drongo/bip47/PaymentCode.java index ecdf87e..d997809 100644 --- a/src/main/java/com/sparrowwallet/drongo/bip47/PaymentCode.java +++ b/src/main/java/com/sparrowwallet/drongo/bip47/PaymentCode.java @@ -38,6 +38,9 @@ public class PaymentCode { private final byte[] pubkey; private final byte[] chain; + public static final List SEGWIT_SCRIPT_TYPES = List.of(ScriptType.P2PKH, ScriptType.P2SH_P2WPKH, ScriptType.P2WPKH); + public static final List V1_SCRIPT_TYPES = List.of(ScriptType.P2PKH); + private PaymentCode(String strPaymentCode, byte[] pubkey, byte[] chain) { this.strPaymentCode = strPaymentCode; this.pubkey = pubkey; diff --git a/src/main/java/com/sparrowwallet/drongo/protocol/Bech32.java b/src/main/java/com/sparrowwallet/drongo/protocol/Bech32.java index 7ed7f16..b625fec 100644 --- a/src/main/java/com/sparrowwallet/drongo/protocol/Bech32.java +++ b/src/main/java/com/sparrowwallet/drongo/protocol/Bech32.java @@ -150,10 +150,14 @@ public class Bech32 { /** Decode a Bech32 string. */ public static Bech32Data decode(final String str) { + return decode(str, 90); + } + + public static Bech32Data decode(final String str, int limit) { boolean lower = false, upper = false; if (str.length() < 8) throw new ProtocolException("Input too short: " + str.length()); - if (str.length() > 90) + if (str.length() > limit) throw new ProtocolException("Input too long: " + str.length()); for (int i = 0; i < str.length(); ++i) { char c = str.charAt(i); diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java index fe48d3e..1aa0129 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java @@ -185,7 +185,7 @@ public class Wallet extends Persistable implements Comparable { throw new IllegalStateException("Cannot add payment code wallet to " + policyType.getName() + " wallet"); } - if(scriptType != P2PKH && scriptType != P2SH_P2WPKH && scriptType != P2WPKH) { + if(!PaymentCode.SEGWIT_SCRIPT_TYPES.contains(scriptType)) { throw new IllegalStateException("Cannot add payment code wallet to " + scriptType.getName() + " wallet"); } @@ -246,7 +246,7 @@ public class Wallet extends Persistable implements Comparable { public boolean hasPaymentCode() { return getKeystores().size() == 1 && getKeystores().get(0).getBip47ExtendedPrivateKey() != null && policyType == PolicyType.SINGLE - && (scriptType == P2PKH || scriptType == P2SH_P2WPKH || scriptType == P2WPKH); + && PaymentCode.SEGWIT_SCRIPT_TYPES.contains(scriptType); } public PaymentCode getPaymentCode() { From aa459d0084b3cc72c49c8922d571338c4f5efaf4 Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Mon, 22 Aug 2022 11:32:45 +0200 Subject: [PATCH 147/155] ensure finalizing psbt wallet purpose nodes have no children --- .../com/sparrowwallet/drongo/wallet/FinalizingPSBTWallet.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/FinalizingPSBTWallet.java b/src/main/java/com/sparrowwallet/drongo/wallet/FinalizingPSBTWallet.java index 5a4dff7..858709d 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/FinalizingPSBTWallet.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/FinalizingPSBTWallet.java @@ -64,6 +64,9 @@ public class FinalizingPSBTWallet extends Wallet { } } + setGapLimit(0); + purposeNode.setChildren(new TreeSet<>()); + setPolicyType(numSignatures == 1 ? PolicyType.SINGLE : PolicyType.MULTI); } From 311afd0409b7cb442e5ee1efebdc3c7dd628346a Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Mon, 22 Aug 2022 14:32:20 +0200 Subject: [PATCH 148/155] add eps wallet model --- src/main/java/com/sparrowwallet/drongo/wallet/WalletModel.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/WalletModel.java b/src/main/java/com/sparrowwallet/drongo/wallet/WalletModel.java index 628958e..2df27a7 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/WalletModel.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/WalletModel.java @@ -3,7 +3,7 @@ package com.sparrowwallet.drongo.wallet; import java.util.Locale; public enum WalletModel { - SEED, SPARROW, BITCOIN_CORE, ELECTRUM, TREZOR_1, TREZOR_T, COLDCARD, LEDGER_NANO_S, LEDGER_NANO_X, DIGITALBITBOX_01, KEEPKEY, SPECTER_DESKTOP, COBO_VAULT, BITBOX_02, SPECTER_DIY, PASSPORT, BLUE_WALLET, KEYSTONE, SEEDSIGNER, CARAVAN, GORDIAN_SEED_TOOL, JADE, LEDGER_NANO_S_PLUS; + SEED, SPARROW, BITCOIN_CORE, ELECTRUM, TREZOR_1, TREZOR_T, COLDCARD, LEDGER_NANO_S, LEDGER_NANO_X, DIGITALBITBOX_01, KEEPKEY, SPECTER_DESKTOP, COBO_VAULT, BITBOX_02, SPECTER_DIY, PASSPORT, BLUE_WALLET, KEYSTONE, SEEDSIGNER, CARAVAN, GORDIAN_SEED_TOOL, JADE, LEDGER_NANO_S_PLUS, EPS; public static WalletModel getModel(String model) { return valueOf(model.toUpperCase(Locale.ROOT)); From 189ef88b08e4aa430315e1e312046c833331bd91 Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Fri, 2 Sep 2022 11:27:12 +0200 Subject: [PATCH 149/155] verify signatures immediately after signing as per recommendation in bip340 --- .../sparrowwallet/drongo/crypto/ECKey.java | 19 +++++++++++++++ .../sparrowwallet/drongo/psbt/PSBTInput.java | 23 ++++++++----------- 2 files changed, 28 insertions(+), 14 deletions(-) diff --git a/src/main/java/com/sparrowwallet/drongo/crypto/ECKey.java b/src/main/java/com/sparrowwallet/drongo/crypto/ECKey.java index 6fa2e92..044e274 100644 --- a/src/main/java/com/sparrowwallet/drongo/crypto/ECKey.java +++ b/src/main/java/com/sparrowwallet/drongo/crypto/ECKey.java @@ -351,6 +351,25 @@ public class ECKey { return pub.isCompressed(); } + public TransactionSignature sign(Sha256Hash input, SigHash sigHash, TransactionSignature.Type type) { + TransactionSignature transactionSignature; + + if(type == TransactionSignature.Type.SCHNORR) { + SchnorrSignature schnorrSignature = signSchnorr(input); + transactionSignature = new TransactionSignature(schnorrSignature, sigHash); + } else { + ECDSASignature ecdsaSignature = signEcdsa(input); + transactionSignature = new TransactionSignature(ecdsaSignature, sigHash); + } + + //Verify transaction signature immediately after signing as recommended in BIP340 + if(!transactionSignature.verify(input.getBytes(), this)) { + throw new IllegalStateException("Generated signature failed verification"); + } + + return transactionSignature; + } + /** * Signs the given hash and returns the R and S components as an ECDSASignature. */ diff --git a/src/main/java/com/sparrowwallet/drongo/psbt/PSBTInput.java b/src/main/java/com/sparrowwallet/drongo/psbt/PSBTInput.java index dbc0145..8bbae7e 100644 --- a/src/main/java/com/sparrowwallet/drongo/psbt/PSBTInput.java +++ b/src/main/java/com/sparrowwallet/drongo/psbt/PSBTInput.java @@ -2,9 +2,7 @@ package com.sparrowwallet.drongo.psbt; import com.sparrowwallet.drongo.KeyDerivation; import com.sparrowwallet.drongo.Utils; -import com.sparrowwallet.drongo.crypto.ECDSASignature; import com.sparrowwallet.drongo.crypto.ECKey; -import com.sparrowwallet.drongo.crypto.SchnorrSignature; import com.sparrowwallet.drongo.protocol.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -14,6 +12,7 @@ import java.util.*; import java.util.stream.Collectors; import static com.sparrowwallet.drongo.protocol.ScriptType.*; +import static com.sparrowwallet.drongo.protocol.TransactionSignature.Type.*; import static com.sparrowwallet.drongo.psbt.PSBTEntry.*; public class PSBTInput { @@ -136,7 +135,7 @@ public class PSBTInput { break; } //TODO: Verify signature - TransactionSignature signature = TransactionSignature.decodeFromBitcoin(TransactionSignature.Type.ECDSA, entry.getData(), true); + TransactionSignature signature = TransactionSignature.decodeFromBitcoin(ECDSA, entry.getData(), true); this.partialSignatures.put(sigPublicKey, signature); log.debug("Found input partial signature with public key " + sigPublicKey + " signature " + Utils.bytesToHex(entry.getData())); break; @@ -221,7 +220,7 @@ public class PSBTInput { break; case PSBT_IN_TAP_KEY_SIG: entry.checkOneByteKey(); - this.tapKeyPathSignature = TransactionSignature.decodeFromBitcoin(TransactionSignature.Type.SCHNORR, entry.getData(), true); + this.tapKeyPathSignature = TransactionSignature.decodeFromBitcoin(SCHNORR, entry.getData(), true); log.debug("Found input taproot key path signature " + Utils.bytesToHex(entry.getData())); break; case PSBT_IN_TAP_BIP32_DERIVATION: @@ -529,21 +528,17 @@ public class PSBTInput { Script signingScript = getSigningScript(); if(signingScript != null) { Sha256Hash hash = getHashForSignature(signingScript, localSigHash); + TransactionSignature.Type type = isTaproot() ? SCHNORR : ECDSA; + TransactionSignature transactionSignature = privKey.sign(hash, localSigHash, type); - if(isTaproot()) { - SchnorrSignature schnorrSignature = privKey.signSchnorr(hash); - tapKeyPathSignature = new TransactionSignature(schnorrSignature, localSigHash); - - return true; + if(type == SCHNORR) { + tapKeyPathSignature = transactionSignature; } else { - ECDSASignature ecdsaSignature = privKey.signEcdsa(hash); - TransactionSignature transactionSignature = new TransactionSignature(ecdsaSignature, localSigHash); - ECKey pubKey = ECKey.fromPublicOnly(privKey); getPartialSignatures().put(pubKey, transactionSignature); - - return true; } + + return true; } } From 60cb3ed85f46c3f1b7ddd071e6b02eb1ac334bb6 Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Mon, 26 Sep 2022 13:47:54 +0200 Subject: [PATCH 150/155] ignore invalid characters when calculating output descriptor checksum --- src/main/java/com/sparrowwallet/drongo/OutputDescriptor.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/sparrowwallet/drongo/OutputDescriptor.java b/src/main/java/com/sparrowwallet/drongo/OutputDescriptor.java index 71823cb..154bae2 100644 --- a/src/main/java/com/sparrowwallet/drongo/OutputDescriptor.java +++ b/src/main/java/com/sparrowwallet/drongo/OutputDescriptor.java @@ -401,7 +401,7 @@ public class OutputDescriptor { int pos = INPUT_CHARSET.indexOf(ch); if(pos < 0) { - return ""; + continue; } c = polyMod(c, pos & 31); // Emit a symbol for the position inside the group, for every character. From f183146d13c61f71ee6df77bf40a56677077ab6b Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Thu, 6 Oct 2022 14:35:29 +0200 Subject: [PATCH 151/155] add linux aarch64 libsecp256k1 --- .../java/org/bitcoin/Secp256k1Context.java | 2 ++ .../native/linux/aarch64/libsecp256k1.so | Bin 0 -> 1109848 bytes 2 files changed, 2 insertions(+) create mode 100644 src/main/resources/native/linux/aarch64/libsecp256k1.so diff --git a/src/main/java/org/bitcoin/Secp256k1Context.java b/src/main/java/org/bitcoin/Secp256k1Context.java index 39494b5..c5276d9 100644 --- a/src/main/java/org/bitcoin/Secp256k1Context.java +++ b/src/main/java/org/bitcoin/Secp256k1Context.java @@ -42,6 +42,8 @@ public class Secp256k1Context { NativeUtils.loadLibraryFromJar("/native/osx/x64/libsecp256k1.dylib"); } else if(osName.startsWith("Windows")) { NativeUtils.loadLibraryFromJar("/native/windows/x64/libsecp256k1-0.dll"); + } else if(osArch.equals("aarch64")) { + NativeUtils.loadLibraryFromJar("/native/linux/aarch64/libsecp256k1.so"); } else { NativeUtils.loadLibraryFromJar("/native/linux/x64/libsecp256k1.so"); } diff --git a/src/main/resources/native/linux/aarch64/libsecp256k1.so b/src/main/resources/native/linux/aarch64/libsecp256k1.so new file mode 100644 index 0000000000000000000000000000000000000000..5b3986017e86acd9747f5733cb2ebe00844e923f GIT binary patch literal 1109848 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

  • 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 bNhecfnJ-yl=_hqEH^9RR(GQya-H`tSr&?wa literal 0 HcmV?d00001 From 5013a0ef2fd0c80d4a568891c77361ed0c436173 Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Thu, 8 Jul 2021 11:45:39 +0200 Subject: [PATCH 045/155] rename tx segwit version field to segwit flag --- .../drongo/protocol/Transaction.java | 18 +++++++++--------- .../com/sparrowwallet/drongo/psbt/PSBT.java | 2 +- .../sparrowwallet/drongo/wallet/Wallet.java | 2 +- .../drongo/protocol/TransactionTest.java | 12 ++++++------ 4 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/main/java/com/sparrowwallet/drongo/protocol/Transaction.java b/src/main/java/com/sparrowwallet/drongo/protocol/Transaction.java index a3c2ab5..59f24e0 100644 --- a/src/main/java/com/sparrowwallet/drongo/protocol/Transaction.java +++ b/src/main/java/com/sparrowwallet/drongo/protocol/Transaction.java @@ -22,7 +22,7 @@ public class Transaction extends ChildMessage { public static final long SATOSHIS_PER_BITCOIN = 100 * 1000 * 1000L; public static final long MAX_BLOCK_LOCKTIME = 500000000L; public static final int WITNESS_SCALE_FACTOR = 4; - public static final int DEFAULT_SEGWIT_VERSION = 1; + public static final int DEFAULT_SEGWIT_FLAG = 1; //Min feerate for defining dust, defined in sats/vByte //From: https://github.com/bitcoin/bitcoin/blob/0.19/src/policy/policy.h#L50 @@ -34,7 +34,7 @@ public class Transaction extends ChildMessage { private long version; private long locktime; private boolean segwit; - private int segwitVersion; + private int segwitFlag; private Sha256Hash cachedTxId; private Sha256Hash cachedWTxId; @@ -134,17 +134,17 @@ public class Transaction extends ChildMessage { return segwit; } - public int getSegwitVersion() { - return segwitVersion; + public int getSegwitFlag() { + return segwitFlag; } - public void setSegwitVersion(int segwitVersion) { + public void setSegwitFlag(int segwitFlag) { if(!segwit) { adjustLength(2); this.segwit = true; } - this.segwitVersion = segwitVersion; + this.segwitFlag = segwitFlag; } public void clearSegwit() { @@ -208,7 +208,7 @@ public class Transaction extends ChildMessage { // marker, flag if(useWitnessFormat) { stream.write(0); - stream.write(segwitVersion); + stream.write(segwitFlag); } // txin_count, txins @@ -253,7 +253,7 @@ public class Transaction extends ChildMessage { // marker, flag if (segwit) { byte[] segwitHeader = readBytes(2); - segwitVersion = segwitHeader[1]; + segwitFlag = segwitHeader[1]; } // txin_count, txins parseInputs(); @@ -352,7 +352,7 @@ public class Transaction extends ChildMessage { public TransactionInput addInput(Sha256Hash spendTxHash, long outputIndex, Script script, TransactionWitness witness) { if(!isSegwit()) { - setSegwitVersion(DEFAULT_SEGWIT_VERSION); + setSegwitFlag(DEFAULT_SEGWIT_FLAG); } return addInput(new TransactionInput(this, new TransactionOutPoint(spendTxHash, outputIndex), script.getProgram(), witness)); diff --git a/src/main/java/com/sparrowwallet/drongo/psbt/PSBT.java b/src/main/java/com/sparrowwallet/drongo/psbt/PSBT.java index 38af19c..3e15391 100644 --- a/src/main/java/com/sparrowwallet/drongo/psbt/PSBT.java +++ b/src/main/java/com/sparrowwallet/drongo/psbt/PSBT.java @@ -542,7 +542,7 @@ public class PSBT { Transaction finalTransaction = new Transaction(transaction.bitcoinSerialize()); if(hasWitness && !finalTransaction.isSegwit()) { - finalTransaction.setSegwitVersion(1); + finalTransaction.setSegwitFlag(Transaction.DEFAULT_SEGWIT_FLAG); } for(int i = 0; i < finalTransaction.getInputs().size(); i++) { diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java index 1d8eac9..5d4344f 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java @@ -443,7 +443,7 @@ public class Wallet extends Persistable { public int getNoInputsWeightUnits(List payments) { Transaction transaction = new Transaction(); if(Arrays.asList(ScriptType.WITNESS_TYPES).contains(getScriptType())) { - transaction.setSegwitVersion(1); + transaction.setSegwitFlag(Transaction.DEFAULT_SEGWIT_FLAG); } for(Payment payment : payments) { transaction.addOutput(payment.getAmount(), payment.getAddress()); diff --git a/src/test/java/com/sparrowwallet/drongo/protocol/TransactionTest.java b/src/test/java/com/sparrowwallet/drongo/protocol/TransactionTest.java index b7bd516..a913f1f 100644 --- a/src/test/java/com/sparrowwallet/drongo/protocol/TransactionTest.java +++ b/src/test/java/com/sparrowwallet/drongo/protocol/TransactionTest.java @@ -162,7 +162,7 @@ public class TransactionTest { Transaction transaction = new Transaction(); transaction.setVersion(parsedTransaction.getVersion()); - transaction.setSegwitVersion(parsedTransaction.getSegwitVersion()); + transaction.setSegwitFlag(parsedTransaction.getSegwitFlag()); for(TransactionInput txInput : parsedTransaction.getInputs()) { transaction.addInput(txInput.getOutpoint().getHash(), txInput.getOutpoint().getIndex(), txInput.getScriptSig(), txInput.getWitness()); } @@ -188,7 +188,7 @@ public class TransactionTest { Transaction transaction = new Transaction(); transaction.setVersion(parsedTransaction.getVersion()); - transaction.setSegwitVersion(parsedTransaction.getSegwitVersion()); + transaction.setSegwitFlag(parsedTransaction.getSegwitFlag()); transaction.setLocktime(parsedTransaction.getLocktime()); for(TransactionInput txInput : parsedTransaction.getInputs()) { TransactionInput newInput = transaction.addInput(txInput.getOutpoint().getHash(), txInput.getOutpoint().getIndex(), txInput.getScriptSig(), txInput.getWitness()); @@ -344,7 +344,7 @@ public class TransactionTest { ECKey pubKey0 = ECKey.fromPublicOnly(witness0.getPushes().get(1)); Transaction transaction = new Transaction(); - transaction.setSegwitVersion(1); + transaction.setSegwitFlag(1); TransactionInput input = ScriptType.P2SH_P2WPKH.addSpendingInput(transaction, spent0Output, pubKey0, signature0); input.setSequenceNumber(TransactionInput.SEQUENCE_RBF_ENABLED); @@ -388,7 +388,7 @@ public class TransactionTest { pubKeySignatures.put(key2, null); Transaction transaction = new Transaction(); - transaction.setSegwitVersion(1); + transaction.setSegwitFlag(1); TransactionInput input = ScriptType.P2SH_P2WSH.addMultisigSpendingInput(transaction, spent0Output, 2, pubKeySignatures); transaction.addOutput(59287429, Address.fromString("3PBjKH4FRuEKy4sD3NfL7tqfZTG5K42owu")); @@ -422,7 +422,7 @@ public class TransactionTest { Transaction transaction = new Transaction(); transaction.setVersion(2); - transaction.setSegwitVersion(1); + transaction.setSegwitFlag(1); spent0ScriptType.addSpendingInput(transaction, spent0Output, key0, signature0); transaction.addOutput(211584990, Address.fromString("bc1q9k6aan6ncahvlslw8w54jzv897k55zh077un6s")); @@ -464,7 +464,7 @@ public class TransactionTest { pubKeySignatures.put(key2, null); Transaction transaction = new Transaction(); - transaction.setSegwitVersion(1); + transaction.setSegwitFlag(1); spent0ScriptType.addMultisigSpendingInput(transaction, spent0Output, 2, pubKeySignatures); transaction.addOutput(10900000, Address.fromString("3Dt17mpd8FDXBjP56rCD7a4Sx7wpL91uhn")); From e53574ea542aa8311dba61e18658482611d74632 Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Fri, 9 Jul 2021 13:33:35 +0200 Subject: [PATCH 046/155] support p2tr script type wallet creation --- .../sparrowwallet/drongo/crypto/ECKey.java | 40 +++++++++++++++++-- .../drongo/policy/Miniscript.java | 6 +++ .../sparrowwallet/drongo/protocol/Script.java | 5 +++ .../drongo/protocol/ScriptType.java | 26 +++++++----- 4 files changed, 64 insertions(+), 13 deletions(-) diff --git a/src/main/java/com/sparrowwallet/drongo/crypto/ECKey.java b/src/main/java/com/sparrowwallet/drongo/crypto/ECKey.java index d62f852..5922d11 100644 --- a/src/main/java/com/sparrowwallet/drongo/crypto/ECKey.java +++ b/src/main/java/com/sparrowwallet/drongo/crypto/ECKey.java @@ -17,10 +17,7 @@ import org.bouncycastle.crypto.params.ECKeyGenerationParameters; import org.bouncycastle.crypto.params.ECPrivateKeyParameters; import org.bouncycastle.crypto.params.ECPublicKeyParameters; import org.bouncycastle.crypto.signers.ECDSASigner; -import org.bouncycastle.math.ec.ECAlgorithms; -import org.bouncycastle.math.ec.ECPoint; -import org.bouncycastle.math.ec.FixedPointCombMultiplier; -import org.bouncycastle.math.ec.FixedPointUtil; +import org.bouncycastle.math.ec.*; import org.bouncycastle.math.ec.custom.sec.SecP256K1Curve; import org.bouncycastle.util.Properties; import org.bouncycastle.util.encoders.Hex; @@ -30,6 +27,7 @@ import org.slf4j.LoggerFactory; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.math.BigInteger; +import java.nio.ByteBuffer; import java.nio.charset.StandardCharsets; import java.security.SecureRandom; import java.security.SignatureException; @@ -628,6 +626,40 @@ public class ECKey implements EncryptableItem { } } + public ECKey getTweakedOutputKey() { + ECPoint internalKey = liftX(getPubKeyXCoord()); + byte[] taggedHash = taggedHash("TapTweak", internalKey.getXCoord().getEncoded()); + ECPoint outputKey = internalKey.add(ECKey.fromPrivate(taggedHash).getPubKeyPoint()); + return ECKey.fromPublicOnly(outputKey, true); + } + + private static ECPoint liftX(byte[] bytes) { + SecP256K1Curve secP256K1Curve = (SecP256K1Curve)CURVE_PARAMS.getCurve(); + BigInteger x = new BigInteger(1, bytes); + BigInteger p = secP256K1Curve.getQ(); + if(x.compareTo(p) > -1) { + throw new IllegalArgumentException("Provided bytes must be less than secp256k1 field size"); + } + + BigInteger y_sq = x.modPow(BigInteger.valueOf(3), p).add(BigInteger.valueOf(7)).mod(p); + BigInteger y = y_sq.modPow(p.add(BigInteger.valueOf(1)).divide(BigInteger.valueOf(4)), p); + if(!y.modPow(BigInteger.valueOf(2), p).equals(y_sq)) { + throw new IllegalStateException("Calculated invalid y_sq when solving for y co-ordinate"); + } + + return secP256K1Curve.createPoint(x, y.and(BigInteger.ONE).equals(BigInteger.ZERO) ? y : p.subtract(y)); + } + + private static byte[] taggedHash(String tag, byte[] msg) { + byte[] hash = Sha256Hash.hash(tag.getBytes(StandardCharsets.UTF_8)); + ByteBuffer buffer = ByteBuffer.allocate(hash.length + hash.length + msg.length); + buffer.put(hash); + buffer.put(hash); + buffer.put(msg); + + return Sha256Hash.hash(buffer.array()); + } + /** * Returns true if the given pubkey is canonical, i.e. the correct length taking into account compression. */ diff --git a/src/main/java/com/sparrowwallet/drongo/policy/Miniscript.java b/src/main/java/com/sparrowwallet/drongo/policy/Miniscript.java index c372540..98294b5 100644 --- a/src/main/java/com/sparrowwallet/drongo/policy/Miniscript.java +++ b/src/main/java/com/sparrowwallet/drongo/policy/Miniscript.java @@ -5,6 +5,7 @@ import java.util.regex.Pattern; public class Miniscript { private static final Pattern SINGLE_PATTERN = Pattern.compile("pkh?\\("); + private static final Pattern TAPROOT_PATTERN = Pattern.compile("tr\\("); private static final Pattern MULTI_PATTERN = Pattern.compile("multi\\(([\\d+])"); private String script; @@ -27,6 +28,11 @@ public class Miniscript { return 1; } + Matcher taprootMatcher = TAPROOT_PATTERN.matcher(script); + if(taprootMatcher.find()) { + return 1; + } + Matcher multiMatcher = MULTI_PATTERN.matcher(script); if(multiMatcher.find()) { String threshold = multiMatcher.group(1); diff --git a/src/main/java/com/sparrowwallet/drongo/protocol/Script.java b/src/main/java/com/sparrowwallet/drongo/protocol/Script.java index 36f5d41..3dd051f 100644 --- a/src/main/java/com/sparrowwallet/drongo/protocol/Script.java +++ b/src/main/java/com/sparrowwallet/drongo/protocol/Script.java @@ -175,6 +175,11 @@ public class Script { } } + //Special handling for taproot tweaked keys - we don't want to tweak them again + if(P2TR.isScriptType(this)) { + return new Address[] { new P2TRAddress(P2TR.getPublicKeyFromScript(this).getPubKeyXCoord()) }; + } + for(ScriptType scriptType : SINGLE_KEY_TYPES) { if(scriptType.isScriptType(this)) { return new Address[] { scriptType.getAddress(scriptType.getPublicKeyFromScript(this)) }; diff --git a/src/main/java/com/sparrowwallet/drongo/protocol/ScriptType.java b/src/main/java/com/sparrowwallet/drongo/protocol/ScriptType.java index 8e07b8c..81a799f 100644 --- a/src/main/java/com/sparrowwallet/drongo/protocol/ScriptType.java +++ b/src/main/java/com/sparrowwallet/drongo/protocol/ScriptType.java @@ -975,15 +975,15 @@ public enum ScriptType { return List.of(MULTI, CUSTOM); } }, - P2TR("P2TR", "Taproot (P2TR)", "m/6789'/0'/0'") { + P2TR("P2TR", "Taproot (P2TR)", "m/86'/0'/0'") { @Override public Address getAddress(byte[] pubKey) { return new P2TRAddress(pubKey); } @Override - public Address getAddress(ECKey key) { - return getAddress(key.getPubKeyXCoord()); + public Address getAddress(ECKey derivedKey) { + return getAddress(derivedKey.getTweakedOutputKey().getPubKeyXCoord()); } @Override @@ -1001,8 +1001,8 @@ public enum ScriptType { } @Override - public Script getOutputScript(ECKey key) { - return getOutputScript(key.getPubKeyXCoord()); + public Script getOutputScript(ECKey derivedKey) { + return getOutputScript(derivedKey.getTweakedOutputKey().getPubKeyXCoord()); } @Override @@ -1011,8 +1011,8 @@ public enum ScriptType { } @Override - public String getOutputDescriptor(ECKey key) { - return getDescriptor() + Utils.bytesToHex(key.getPubKeyXCoord()) + getCloseDescriptor(); + public String getOutputDescriptor(ECKey derivedKey) { + return getDescriptor() + Utils.bytesToHex(derivedKey.getPubKeyXCoord()) + getCloseDescriptor(); } @Override @@ -1052,7 +1052,15 @@ public enum ScriptType { @Override public Script getScriptSig(Script scriptPubKey, ECKey pubKey, TransactionSignature signature) { - throw new UnsupportedOperationException("Constructing Taproot inputs is not yet supported"); + if(!isScriptType(scriptPubKey)) { + throw new ProtocolException("Provided scriptPubKey is not a " + getName() + " script"); + } + + if(!scriptPubKey.equals(getOutputScript(pubKey))) { + throw new ProtocolException("Provided P2TR scriptPubKey does not match constructed pubkey script"); + } + + return new Script(new byte[0]); } @Override @@ -1072,7 +1080,7 @@ public enum ScriptType { @Override public List getAllowedPolicyTypes() { - return Collections.emptyList(); + return Network.get() == Network.REGTEST || Network.get() == Network.SIGNET ? List.of(SINGLE) : Collections.emptyList(); } }; From f1ce2ec939743e24dcd1d8426f3b68e8971c2be0 Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Mon, 12 Jul 2021 08:55:31 +0200 Subject: [PATCH 047/155] refactor ECKey and TransactionSignature to support schnorr --- .../drongo/crypto/ECDSASignature.java | 254 ++++++++++ .../sparrowwallet/drongo/crypto/ECKey.java | 473 ++---------------- .../drongo/crypto/SchnorrSignature.java | 80 +++ .../drongo/protocol/ScriptChunk.java | 6 +- .../drongo/protocol/ScriptType.java | 47 ++ .../drongo/protocol/SigHash.java | 2 +- .../drongo/protocol/TransactionSignature.java | 177 +++---- .../sparrowwallet/drongo/psbt/PSBTInput.java | 5 +- .../sparrowwallet/drongo/wallet/Wallet.java | 8 +- .../drongo/crypto/ECKeyTest.java | 6 +- .../drongo/protocol/TransactionTest.java | 32 +- 11 files changed, 517 insertions(+), 573 deletions(-) create mode 100644 src/main/java/com/sparrowwallet/drongo/crypto/ECDSASignature.java create mode 100644 src/main/java/com/sparrowwallet/drongo/crypto/SchnorrSignature.java diff --git a/src/main/java/com/sparrowwallet/drongo/crypto/ECDSASignature.java b/src/main/java/com/sparrowwallet/drongo/crypto/ECDSASignature.java new file mode 100644 index 0000000..0a7c6eb --- /dev/null +++ b/src/main/java/com/sparrowwallet/drongo/crypto/ECDSASignature.java @@ -0,0 +1,254 @@ +package com.sparrowwallet.drongo.crypto; + +import com.sparrowwallet.drongo.protocol.SigHash; +import com.sparrowwallet.drongo.protocol.SignatureDecodeException; +import com.sparrowwallet.drongo.protocol.TransactionSignature; +import com.sparrowwallet.drongo.protocol.VerificationException; +import org.bouncycastle.asn1.*; +import org.bouncycastle.crypto.params.ECPublicKeyParameters; +import org.bouncycastle.crypto.signers.ECDSASigner; +import org.bouncycastle.util.Properties; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.math.BigInteger; +import java.util.Objects; + +import static com.sparrowwallet.drongo.crypto.ECKey.CURVE; + +/** + * Groups the two components that make up a signature, and provides a way to encode to DER form, which is + * how ECDSA signatures are represented when embedded in other data structures in the Bitcoin protocol. The raw + * components can be useful for doing further EC maths on them. + */ +public class ECDSASignature { + private static final Logger log = LoggerFactory.getLogger(ECDSASignature.class); + + /** + * The two components of the signature. + */ + public final BigInteger r, s; + + /** + * Constructs a signature with the given components. Does NOT automatically canonicalise the signature. + */ + public ECDSASignature(BigInteger r, BigInteger s) { + this.r = r; + this.s = s; + } + + /** + * Returns true if the S component is "low", that means it is below {@link ECKey#HALF_CURVE_ORDER}. See BIP62. + */ + public boolean isCanonical() { + return s.compareTo(ECKey.HALF_CURVE_ORDER) <= 0; + } + + /** + * Will automatically adjust the S component to be less than or equal to half the curve order, if necessary. + * This is required because for every signature (r,s) the signature (r, -s (mod N)) is a valid signature of + * the same message. However, we dislike the ability to modify the bits of a Bitcoin transaction after it's + * been signed, as that violates various assumed invariants. Thus in future only one of those forms will be + * considered legal and the other will be banned. + */ + public ECDSASignature toCanonicalised() { + if(!isCanonical()) { + // The order of the curve is the number of valid points that exist on that curve. If S is in the upper + // half of the number of valid points, then bring it back to the lower half. Otherwise, imagine that + // N = 10 + // s = 8, so (-8 % 10 == 2) thus both (r, 8) and (r, 2) are valid solutions. + // 10 - 8 == 2, giving us always the latter solution, which is canonical. + return new ECDSASignature(r, CURVE.getN().subtract(s)); + } else { + return this; + } + } + + /** + * DER is an international standard for serializing data structures which is widely used in cryptography. + * It's somewhat like protocol buffers but less convenient. This method returns a standard DER encoding + * of the signature, as recognized by OpenSSL and other libraries. + */ + public byte[] encodeToDER() { + try { + return derByteStream().toByteArray(); + } catch(IOException e) { + throw new RuntimeException(e); // Cannot happen. + } + } + + /** + * @throws SignatureDecodeException if the signature is unparseable in some way. + */ + public static ECDSASignature decodeFromDER(byte[] bytes) throws SignatureDecodeException { + ASN1InputStream decoder = null; + try { + // BouncyCastle by default is strict about parsing ASN.1 integers. We relax this check, because some + // Bitcoin signatures would not parse. + Properties.setThreadOverride("org.bouncycastle.asn1.allow_unsafe_integer", true); + decoder = new ASN1InputStream(bytes); + final ASN1Primitive seqObj = decoder.readObject(); + if(seqObj == null) { + throw new SignatureDecodeException("Reached past end of ASN.1 stream."); + } + if(!(seqObj instanceof DLSequence)) { + throw new SignatureDecodeException("Read unexpected class: " + seqObj.getClass().getName()); + } + final DLSequence seq = (DLSequence) seqObj; + ASN1Integer r, s; + try { + r = (ASN1Integer) seq.getObjectAt(0); + s = (ASN1Integer) seq.getObjectAt(1); + } catch(ClassCastException e) { + throw new SignatureDecodeException(e); + } + // OpenSSL deviates from the DER spec by interpreting these values as unsigned, though they should not be + // Thus, we always use the positive versions. See: http://r6.ca/blog/20111119T211504Z.html + return new ECDSASignature(r.getPositiveValue(), s.getPositiveValue()); + } catch(IOException e) { + throw new SignatureDecodeException(e); + } finally { + if(decoder != null) { + try { + decoder.close(); + } catch(IOException x) { + } + } + Properties.removeThreadOverride("org.bouncycastle.asn1.allow_unsafe_integer"); + } + } + + /** + *