Search in sources :

Example 1 with ChildNumber

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

the class OutputDescriptor method getChangeDerivation.

public List<ChildNumber> getChangeDerivation(int wildCardReplacement) {
    if (isMultisig()) {
        List<ChildNumber> path = new ArrayList<>();
        path.add(new ChildNumber(1));
        path.add(new ChildNumber(wildCardReplacement));
        return path;
    }
    return getChangeDerivation(getSingletonExtendedPublicKey(), wildCardReplacement);
}
Also used : ChildNumber(com.sparrowwallet.drongo.crypto.ChildNumber)

Example 2 with ChildNumber

use of com.sparrowwallet.drongo.crypto.ChildNumber 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 3 with ChildNumber

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

the class WalletNode method compareTo.

@Override
public int compareTo(WalletNode node) {
    if (getDerivation().size() != node.getDerivation().size()) {
        return getDerivation().size() - node.getDerivation().size();
    }
    for (int i = 0; i < getDerivation().size(); i++) {
        ChildNumber thisChild = getDerivation().get(i);
        ChildNumber nodeChild = node.getDerivation().get(i);
        if (thisChild.num() != nodeChild.num()) {
            return thisChild.num() - nodeChild.num();
        }
    }
    return 0;
}
Also used : ChildNumber(com.sparrowwallet.drongo.crypto.ChildNumber)

Example 4 with ChildNumber

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

the class PSBTEntry method readBIP32Derivation.

public static List<ChildNumber> readBIP32Derivation(byte[] data) {
    List<ChildNumber> path = new ArrayList<>();
    ByteBuffer bb = ByteBuffer.wrap(data);
    byte[] buf = new byte[4];
    do {
        bb.get(buf);
        Utils.reverse(buf);
        ByteBuffer pbuf = ByteBuffer.wrap(buf);
        path.add(new ChildNumber(pbuf.getInt()));
    } while (bb.hasRemaining());
    return path;
}
Also used : ArrayList(java.util.ArrayList) ChildNumber(com.sparrowwallet.drongo.crypto.ChildNumber) ByteBuffer(java.nio.ByteBuffer)

Example 5 with ChildNumber

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

the class PSBTEntry method serializeKeyDerivation.

public static byte[] serializeKeyDerivation(KeyDerivation keyDerivation) {
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    byte[] fingerprintBytes = Utils.hexToBytes(keyDerivation.getMasterFingerprint());
    if (fingerprintBytes.length != 4) {
        throw new IllegalArgumentException("Invalid number of fingerprint bytes: " + fingerprintBytes.length);
    }
    baos.writeBytes(fingerprintBytes);
    for (ChildNumber childNumber : keyDerivation.getDerivation()) {
        byte[] indexBytes = new byte[4];
        Utils.uint32ToByteArrayLE(childNumber.i(), indexBytes, 0);
        baos.writeBytes(indexBytes);
    }
    return baos.toByteArray();
}
Also used : ByteArrayOutputStream(java.io.ByteArrayOutputStream) ChildNumber(com.sparrowwallet.drongo.crypto.ChildNumber)

Aggregations

ChildNumber (com.sparrowwallet.drongo.crypto.ChildNumber)17 ECKey (com.sparrowwallet.drongo.crypto.ECKey)4 Test (org.junit.Test)4 DeterministicKey (com.sparrowwallet.drongo.crypto.DeterministicKey)3 ArrayList (java.util.ArrayList)3 Wallet (com.sparrowwallet.drongo.wallet.Wallet)2 Insets (javafx.geometry.Insets)2 HBox (javafx.scene.layout.HBox)2 ValidationSupport (org.controlsfx.validation.ValidationSupport)2 StyleClassValidationDecoration (org.controlsfx.validation.decoration.StyleClassValidationDecoration)2 ExtendedKey (com.sparrowwallet.drongo.ExtendedKey)1 KeyDerivation (com.sparrowwallet.drongo.KeyDerivation)1 Address (com.sparrowwallet.drongo.address.Address)1 ScriptType (com.sparrowwallet.drongo.protocol.ScriptType)1 Keystore (com.sparrowwallet.drongo.wallet.Keystore)1 MnemonicException (com.sparrowwallet.drongo.wallet.MnemonicException)1 WalletImportEvent (com.sparrowwallet.sparrow.event.WalletImportEvent)1 ImportException (com.sparrowwallet.sparrow.io.ImportException)1 ElectrumServer (com.sparrowwallet.sparrow.net.ElectrumServer)1 ByteArrayOutputStream (java.io.ByteArrayOutputStream)1