Search in sources :

Example 1 with ECKey

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

the class PSBTInput method getSigningKeys.

public Map<ECKey, TransactionSignature> getSigningKeys(Set<ECKey> availableKeys) {
    Collection<TransactionSignature> signatures = getSignatures();
    Script signingScript = getSigningScript();
    Map<ECKey, TransactionSignature> signingKeys = new LinkedHashMap<>();
    if (signingScript != null) {
        Sha256Hash hash = getHashForSignature(signingScript, getSigHash() == null ? getDefaultSigHash() : getSigHash());
        for (ECKey sigPublicKey : availableKeys) {
            for (TransactionSignature signature : signatures) {
                if (sigPublicKey.verify(hash, signature)) {
                    signingKeys.put(sigPublicKey, signature);
                }
            }
        }
    }
    return signingKeys;
}
Also used : ECKey(com.sparrowwallet.drongo.crypto.ECKey)

Example 2 with ECKey

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

the class PSBTInput method sign.

public boolean sign(ECKey privKey) {
    SigHash localSigHash = getSigHash();
    if (localSigHash == null) {
        localSigHash = getDefaultSigHash();
    }
    if (getNonWitnessUtxo() != null || getWitnessUtxo() != null) {
        Script signingScript = getSigningScript();
        if (signingScript != null) {
            Sha256Hash hash = getHashForSignature(signingScript, localSigHash);
            if (isTaproot()) {
                SchnorrSignature schnorrSignature = privKey.signSchnorr(hash);
                tapKeyPathSignature = new TransactionSignature(schnorrSignature, localSigHash);
                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;
            }
        }
    }
    return false;
}
Also used : SchnorrSignature(com.sparrowwallet.drongo.crypto.SchnorrSignature) ECDSASignature(com.sparrowwallet.drongo.crypto.ECDSASignature) ECKey(com.sparrowwallet.drongo.crypto.ECKey)

Example 3 with ECKey

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

the class PaymentCodeTest method testNotificationAddress.

@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<ScriptChunk> 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<ScriptChunk> 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);
}
Also used : Address(com.sparrowwallet.drongo.address.Address) ECKey(com.sparrowwallet.drongo.crypto.ECKey) ChildNumber(com.sparrowwallet.drongo.crypto.ChildNumber) Test(org.junit.Test)

Example 4 with ECKey

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

the class Wallet method sign.

public void sign(PSBT psbt) throws MnemonicException {
    Map<PSBTInput, WalletNode> signingNodes = getSigningNodes(psbt);
    for (Map.Entry<PSBTInput, WalletNode> 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()) {
                    psbtInput.sign(privKey);
                }
            }
        }
    }
}
Also used : ECKey(com.sparrowwallet.drongo.crypto.ECKey) PSBTInput(com.sparrowwallet.drongo.psbt.PSBTInput)

Example 5 with ECKey

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

the class TransactionTest method signTaprootKeypath.

@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)));
}
Also used : SchnorrSignature(com.sparrowwallet.drongo.crypto.SchnorrSignature) ECKey(com.sparrowwallet.drongo.crypto.ECKey) Test(org.junit.Test)

Aggregations

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