From 2f1644ee16752b596dc64afb3320b2423aeea3b4 Mon Sep 17 00:00:00 2001 From: Toporin Date: Wed, 6 Sep 2023 09:07:40 +0100 Subject: [PATCH 1/4] Add satochip support: initial commit with debug traces todo: clean code --- .../sparrowwallet/drongo/crypto/ECKey.java | 110 ++++++++++++++++++ .../sparrowwallet/drongo/psbt/PSBTInput.java | 78 +++++++++++++ .../drongo/wallet/WalletModel.java | 15 ++- 3 files changed, 202 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/sparrowwallet/drongo/crypto/ECKey.java b/src/main/java/com/sparrowwallet/drongo/crypto/ECKey.java index 996456c..5b6fe67 100644 --- a/src/main/java/com/sparrowwallet/drongo/crypto/ECKey.java +++ b/src/main/java/com/sparrowwallet/drongo/crypto/ECKey.java @@ -307,6 +307,11 @@ public class ECKey { return pub.getEncoded(); } + // SATOCHIP + public byte[] getPubKey(Boolean compressed) { + return pub.getEncoded(compressed); + } + /** * Gets the x coordinate of the raw public key value. This appears in transaction scriptPubKeys for Taproot outputs. */ @@ -428,14 +433,119 @@ public class ECKey { return verify(sigHash.getBytes(), signature); } + public ECKey getTweakedOutputKey() { + log.debug("SATOCHIP ECKey getTweakedOutputKey START"); TaprootPubKey taprootPubKey = liftX(getPubKeyXCoord()); + log.debug("SATOCHIP ECKey getTweakedOutputKey taprootPubKey: " + taprootPubKey); + log.debug("SATOCHIP ECKey getTweakedOutputKey taprootPubKey.ecPoint: " + taprootPubKey.ecPoint); ECPoint internalKey = taprootPubKey.ecPoint; + log.debug("SATOCHIP ECKey getTweakedOutputKey internalKey: " + internalKey); + //debug + ECKey tmp2 = ECKey.fromPublicOnly(internalKey, true); + log.debug("SATOCHIP ECKey getTweakedOutputKey internalKey: " + Utils.bytesToHex(tmp2.getPubKey())); + //endbug + byte[] taggedHash = Utils.taggedHash("TapTweak", internalKey.getXCoord().getEncoded()); ECKey tweakValue = ECKey.fromPrivate(taggedHash); + log.debug("SATOCHIP ECKey getTweakedOutputKey tweakValue: " + Utils.bytesToHex(tweakValue.getPubKey())); ECPoint outputKey = internalKey.add(tweakValue.getPubKeyPoint()); + log.debug("SATOCHIP ECKey getTweakedOutputKey outputKey: " + outputKey); + + //debug + ECKey tmp = ECKey.fromPublicOnly(outputKey, true); + log.debug("SATOCHIP ECKey getTweakedOutputKey outputKey: " + Utils.bytesToHex(tmp.getPubKey())); + //endbug if(hasPrivKey()) { + log.debug("SATOCHIP ECKey getTweakedOutputKey PRIVKEY NEW VERSION"); + + // isEven => used to determine private key for tweaking + Boolean isEven = (getPubKey()[0] == 0x02); + log.debug("SATOCHIP ECKey getTweakedOutputKey getPubKey(): " + Utils.bytesToHex(getPubKey())); + log.debug("SATOCHIP ECKey getTweakedOutputKey isEven getPubKey()[0]: " + getPubKey()[0]); + log.debug("SATOCHIP ECKey getTweakedOutputKey isEven: " + isEven); + + BigInteger taprootPriv; + if (isEven){ + taprootPriv = priv; + } else { + taprootPriv = CURVE_PARAMS.getCurve().getOrder().subtract(priv); + } + BigInteger tweakedPrivKey = taprootPriv.add(tweakValue.getPrivKey()).mod(CURVE_PARAMS.getCurve().getOrder()); + + //debug + ECKey tmp3 = new ECKey(tweakedPrivKey, outputKey, true); + log.debug("SATOCHIP ECKey getTweakedOutputKey outputKey with private: " + Utils.bytesToHex(tmp3.getPubKey())); + log.debug("SATOCHIP ECKey getTweakedOutputKey outputKey private: " + tmp3.getPrivKey()); + //endbug + + +/* log.debug("SATOCHIP ECKey getTweakedOutputKey PRIVKEY NEW VERSION SWITCH EVENNESS"); + if (isEven){ + //taprootPriv = priv; + taprootPriv = CURVE_PARAMS.getCurve().getOrder().subtract(priv); + } else { + taprootPriv = priv; + //taprootPriv = CURVE_PARAMS.getCurve().getOrder().subtract(priv); + } + tweakedPrivKey = taprootPriv.add(tweakValue.getPrivKey()).mod(CURVE_PARAMS.getCurve().getOrder()); + + //debug + ECKey tmp5 = new ECKey(tweakedPrivKey, outputKey, true); + log.debug("SATOCHIP ECKey getTweakedOutputKey outputKey with private: " + Utils.bytesToHex(tmp5.getPubKey())); + log.debug("SATOCHIP ECKey getTweakedOutputKey outputKey private: " + tmp5.getPrivKey()); + //endbug*/ + + +/* // ORIGNAL VERSION + log.debug("SATOCHIP ECKey getTweakedOutputKey PRIVKEY OLD VERSION"); + taprootPriv = priv; + 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()); + } + //debug + ECKey tmp4 = new ECKey(tweakedPrivKey, outputKey, true); + log.debug("SATOCHIP ECKey getTweakedOutputKey outputKey with private: " + Utils.bytesToHex(tmp4.getPubKey())); + log.debug("SATOCHIP ECKey getTweakedOutputKey outputKey private: " + tmp4.getPrivKey()); + //endbug*/ + + + return new ECKey(tweakedPrivKey, outputKey, true); + } + + return ECKey.fromPublicOnly(outputKey, true); + } + + + public ECKey getTweakedOutputKeyOLD() { + log.debug("SATOCHIP ECKey getTweakedOutputKey START"); + TaprootPubKey taprootPubKey = liftX(getPubKeyXCoord()); + log.debug("SATOCHIP ECKey getTweakedOutputKey taprootPubKey: " + taprootPubKey); + log.debug("SATOCHIP ECKey getTweakedOutputKey taprootPubKey.ecPoint: " + taprootPubKey.ecPoint); + ECPoint internalKey = taprootPubKey.ecPoint; + log.debug("SATOCHIP ECKey getTweakedOutputKey internalKey: " + internalKey); + //debug + ECKey tmp2 = ECKey.fromPublicOnly(internalKey, true); + log.debug("SATOCHIP ECKey getTweakedOutputKey outputKey: " + Utils.bytesToHex(tmp2.getPubKey())); + //endbug + + byte[] taggedHash = Utils.taggedHash("TapTweak", internalKey.getXCoord().getEncoded()); + ECKey tweakValue = ECKey.fromPrivate(taggedHash); + log.debug("SATOCHIP ECKey getTweakedOutputKey tweakValue: " + Utils.bytesToHex(tweakValue.getPubKey())); + ECPoint outputKey = internalKey.add(tweakValue.getPubKeyPoint()); + log.debug("SATOCHIP ECKey getTweakedOutputKey outputKey: " + outputKey); + + //debug + ECKey tmp = ECKey.fromPublicOnly(outputKey, true); + log.debug("SATOCHIP ECKey getTweakedOutputKey outputKey: " + Utils.bytesToHex(tmp.getPubKey())); + //endbug + + if(hasPrivKey()) { + log.debug("SATOCHIP ECKey getTweakedOutputKey hasPrivKey(): true"); 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? diff --git a/src/main/java/com/sparrowwallet/drongo/psbt/PSBTInput.java b/src/main/java/com/sparrowwallet/drongo/psbt/PSBTInput.java index eade24e..7681af4 100644 --- a/src/main/java/com/sparrowwallet/drongo/psbt/PSBTInput.java +++ b/src/main/java/com/sparrowwallet/drongo/psbt/PSBTInput.java @@ -250,6 +250,75 @@ public class PSBTInput { this.index = index; } + // satochip debug + public void printDebugInfo(){ + log.debug("SATOCHIP PSBTInput printDebugInfo() START"); + // partialSignatures + try{ + log.debug("SATOCHIP PSBTInput printDebugInfo() partialSignatures: Map"); + log.debug("SATOCHIP PSBTInput printDebugInfo() partialSignatures.size(): " + partialSignatures.size()); + log.debug("SATOCHIP PSBTInput printDebugInfo() partialSignatures: " + partialSignatures); + for (Map.Entry entry : partialSignatures.entrySet()) { + ECKey key = entry.getKey(); + TransactionSignature value = entry.getValue(); + log.debug("SATOCHIP PSBTInput printDebugInfo() partialSignatures pubkey: " + Utils.bytesToHex(key.getPubKey())); + log.debug("SATOCHIP PSBTInput printDebugInfo() partialSignatures sig: " + Utils.bytesToHex(value.encodeToBitcoin())); + } + log.debug("SATOCHIP PSBTInput printDebugInfo() partialSignatures END"); + } catch(Exception e) { + log.debug("SATOCHIP PSBTInput printDebugInfo() partialSignatures exception: " + e); + } + + // derivedPublicKeys + try{ + log.debug("SATOCHIP PSBTInput printDebugInfo() derivedPublicKeys: Map"); + log.debug("SATOCHIP PSBTInput printDebugInfo() derivedPublicKeys.size(): " + derivedPublicKeys.size()); + log.debug("SATOCHIP PSBTInput printDebugInfo() derivedPublicKeys: " + derivedPublicKeys); + for (Map.Entry entry : derivedPublicKeys.entrySet()) { + ECKey key = entry.getKey(); + KeyDerivation value = entry.getValue(); + log.debug("SATOCHIP PSBTInput printDebugInfo() derivedPublicKeys pubkey: " + Utils.bytesToHex(key.getPubKey())); + log.debug("SATOCHIP PSBTInput printDebugInfo() derivedPublicKeys derivation: " + value.getDerivationPath()); + } + log.debug("SATOCHIP PSBTInput printDebugInfo() derivedPublicKeys END"); + } catch(Exception e) { + log.debug("SATOCHIP PSBTInput printDebugInfo() derivedPublicKeys exception: " + e); + } + + // TransactionSignature tapKeyPathSignature; + if (tapKeyPathSignature!=null) { + log.debug("SATOCHIP PSBTInput printDebugInfo() tapKeyPathSignature: " + Utils.bytesToHex(tapKeyPathSignature.encodeToBitcoin())); + } else { + log.debug("SATOCHIP PSBTInput printDebugInfo() tapKeyPathSignature: null"); + } + // ECKey tapInternalKey + if (tapInternalKey!=null) { + log.debug("SATOCHIP PSBTInput printDebugInfo() tapInternalKey: " + Utils.bytesToHex(tapInternalKey.getPubKey())); + } else { + log.debug("SATOCHIP PSBTInput printDebugInfo() tapInternalKey: null"); + } + // tapDerivedPublicKeys + + try { + log.debug("SATOCHIP PSBTInput printDebugInfo() tapDerivedPublicKeys: Map>>"); + log.debug("SATOCHIP PSBTInput printDebugInfo() tapDerivedPublicKeys.size(): " + tapDerivedPublicKeys.size()); + log.debug("SATOCHIP PSBTInput printDebugInfo() tapDerivedPublicKeys: " + tapDerivedPublicKeys); + for (Map.Entry>> entry : tapDerivedPublicKeys.entrySet()) { + ECKey key = entry.getKey(); + Map> value = entry.getValue(); + log.debug("SATOCHIP PSBTInput printDebugInfo() tapDerivedPublicKeys pubkey: " + Utils.bytesToHex(key.getPubKey())); + log.debug("SATOCHIP PSBTInput printDebugInfo() tapDerivedPublicKeys map: " + value); + } + log.debug("SATOCHIP PSBTInput printDebugInfo() tapDerivedPublicKeys END"); + } catch(Exception e) { + log.debug("SATOCHIP PSBTInput printDebugInfo() tapDerivedPublicKeys exception: " + e); + } + + log.debug("SATOCHIP PSBTInput printDebugInfo() END"); + + } + // endbug + public List getInputEntries() { List entries = new ArrayList<>(); @@ -573,6 +642,15 @@ public class PSBTInput { if(isTaproot() && tapKeyPathSignature != null) { ECKey outputKey = P2TR.getPublicKeyFromScript(getUtxo().getScript()); if(!outputKey.verify(hash, tapKeyPathSignature)) { + log.error("SATOCHIP PSBTInput verifySignatures error: " + "Tweaked internal key does not verify against provided taproot keypath signature"); + log.error("SATOCHIP PSBTInput verifySignatures error: psbtinput: " + this); + log.error("SATOCHIP PSBTInput verifySignatures error: outputKey: " + Utils.bytesToHex(outputKey.getPubKey())); + log.error("SATOCHIP PSBTInput verifySignatures error: hash: " + Utils.bytesToHex(hash.getBytes())); + log.error("SATOCHIP PSBTInput verifySignatures error: tapKeyPathSignature: " + Utils.bytesToHex(tapKeyPathSignature.encodeToBitcoin())); + log.error("SATOCHIP PSBTInput verifySignatures error: getUtxo().getScript(): " + getUtxo().getScript()); + log.error("SATOCHIP PSBTInput verifySignatures error: getUtxo(): " + getUtxo()); + log.error("SATOCHIP PSBTInput verifySignatures error: getUtxo().getHash(): " + getUtxo().getHash()); + log.error("SATOCHIP PSBTInput verifySignatures error: getUtxo().getIndex(): " + getUtxo().getIndex()); throw new PSBTSignatureException("Tweaked internal key does not verify against provided taproot keypath signature"); } } else { diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/WalletModel.java b/src/main/java/com/sparrowwallet/drongo/wallet/WalletModel.java index 66586f1..05333f5 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/WalletModel.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/WalletModel.java @@ -4,7 +4,7 @@ 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, EPS, TAPSIGNER, SATSCARD, LABELS, BSMS; + BITBOX_02, SPECTER_DIY, PASSPORT, BLUE_WALLET, KEYSTONE, SEEDSIGNER, CARAVAN, GORDIAN_SEED_TOOL, JADE, LEDGER_NANO_S_PLUS, EPS, TAPSIGNER, SATSCARD, SATOCHIP, LABELS, BSMS; public static WalletModel getModel(String model) { return valueOf(model.toUpperCase(Locale.ROOT)); @@ -70,6 +70,19 @@ public enum WalletModel { return (this == TAPSIGNER || this == SATSCARD); } + // for card devices that require a PIN code, returns the minimum size of valid PIN code + public int getMinPinLength() { + if (this == TAPSIGNER || this == SATSCARD){ + return 6; + } + else if (this == SATOCHIP){ + return 4; + } + else { + return 0; // default? + } + } + public static WalletModel fromType(String type) { for(WalletModel model : values()) { if(model.getType().equalsIgnoreCase(type)) { From 77901915b711a8246e69a0604dab59812886475e Mon Sep 17 00:00:00 2001 From: Toporin Date: Wed, 6 Sep 2023 09:14:25 +0100 Subject: [PATCH 2/4] remove log debug traces from PSBTInput --- .../sparrowwallet/drongo/psbt/PSBTInput.java | 78 ------------------- 1 file changed, 78 deletions(-) diff --git a/src/main/java/com/sparrowwallet/drongo/psbt/PSBTInput.java b/src/main/java/com/sparrowwallet/drongo/psbt/PSBTInput.java index 7681af4..eade24e 100644 --- a/src/main/java/com/sparrowwallet/drongo/psbt/PSBTInput.java +++ b/src/main/java/com/sparrowwallet/drongo/psbt/PSBTInput.java @@ -250,75 +250,6 @@ public class PSBTInput { this.index = index; } - // satochip debug - public void printDebugInfo(){ - log.debug("SATOCHIP PSBTInput printDebugInfo() START"); - // partialSignatures - try{ - log.debug("SATOCHIP PSBTInput printDebugInfo() partialSignatures: Map"); - log.debug("SATOCHIP PSBTInput printDebugInfo() partialSignatures.size(): " + partialSignatures.size()); - log.debug("SATOCHIP PSBTInput printDebugInfo() partialSignatures: " + partialSignatures); - for (Map.Entry entry : partialSignatures.entrySet()) { - ECKey key = entry.getKey(); - TransactionSignature value = entry.getValue(); - log.debug("SATOCHIP PSBTInput printDebugInfo() partialSignatures pubkey: " + Utils.bytesToHex(key.getPubKey())); - log.debug("SATOCHIP PSBTInput printDebugInfo() partialSignatures sig: " + Utils.bytesToHex(value.encodeToBitcoin())); - } - log.debug("SATOCHIP PSBTInput printDebugInfo() partialSignatures END"); - } catch(Exception e) { - log.debug("SATOCHIP PSBTInput printDebugInfo() partialSignatures exception: " + e); - } - - // derivedPublicKeys - try{ - log.debug("SATOCHIP PSBTInput printDebugInfo() derivedPublicKeys: Map"); - log.debug("SATOCHIP PSBTInput printDebugInfo() derivedPublicKeys.size(): " + derivedPublicKeys.size()); - log.debug("SATOCHIP PSBTInput printDebugInfo() derivedPublicKeys: " + derivedPublicKeys); - for (Map.Entry entry : derivedPublicKeys.entrySet()) { - ECKey key = entry.getKey(); - KeyDerivation value = entry.getValue(); - log.debug("SATOCHIP PSBTInput printDebugInfo() derivedPublicKeys pubkey: " + Utils.bytesToHex(key.getPubKey())); - log.debug("SATOCHIP PSBTInput printDebugInfo() derivedPublicKeys derivation: " + value.getDerivationPath()); - } - log.debug("SATOCHIP PSBTInput printDebugInfo() derivedPublicKeys END"); - } catch(Exception e) { - log.debug("SATOCHIP PSBTInput printDebugInfo() derivedPublicKeys exception: " + e); - } - - // TransactionSignature tapKeyPathSignature; - if (tapKeyPathSignature!=null) { - log.debug("SATOCHIP PSBTInput printDebugInfo() tapKeyPathSignature: " + Utils.bytesToHex(tapKeyPathSignature.encodeToBitcoin())); - } else { - log.debug("SATOCHIP PSBTInput printDebugInfo() tapKeyPathSignature: null"); - } - // ECKey tapInternalKey - if (tapInternalKey!=null) { - log.debug("SATOCHIP PSBTInput printDebugInfo() tapInternalKey: " + Utils.bytesToHex(tapInternalKey.getPubKey())); - } else { - log.debug("SATOCHIP PSBTInput printDebugInfo() tapInternalKey: null"); - } - // tapDerivedPublicKeys - - try { - log.debug("SATOCHIP PSBTInput printDebugInfo() tapDerivedPublicKeys: Map>>"); - log.debug("SATOCHIP PSBTInput printDebugInfo() tapDerivedPublicKeys.size(): " + tapDerivedPublicKeys.size()); - log.debug("SATOCHIP PSBTInput printDebugInfo() tapDerivedPublicKeys: " + tapDerivedPublicKeys); - for (Map.Entry>> entry : tapDerivedPublicKeys.entrySet()) { - ECKey key = entry.getKey(); - Map> value = entry.getValue(); - log.debug("SATOCHIP PSBTInput printDebugInfo() tapDerivedPublicKeys pubkey: " + Utils.bytesToHex(key.getPubKey())); - log.debug("SATOCHIP PSBTInput printDebugInfo() tapDerivedPublicKeys map: " + value); - } - log.debug("SATOCHIP PSBTInput printDebugInfo() tapDerivedPublicKeys END"); - } catch(Exception e) { - log.debug("SATOCHIP PSBTInput printDebugInfo() tapDerivedPublicKeys exception: " + e); - } - - log.debug("SATOCHIP PSBTInput printDebugInfo() END"); - - } - // endbug - public List getInputEntries() { List entries = new ArrayList<>(); @@ -642,15 +573,6 @@ public class PSBTInput { if(isTaproot() && tapKeyPathSignature != null) { ECKey outputKey = P2TR.getPublicKeyFromScript(getUtxo().getScript()); if(!outputKey.verify(hash, tapKeyPathSignature)) { - log.error("SATOCHIP PSBTInput verifySignatures error: " + "Tweaked internal key does not verify against provided taproot keypath signature"); - log.error("SATOCHIP PSBTInput verifySignatures error: psbtinput: " + this); - log.error("SATOCHIP PSBTInput verifySignatures error: outputKey: " + Utils.bytesToHex(outputKey.getPubKey())); - log.error("SATOCHIP PSBTInput verifySignatures error: hash: " + Utils.bytesToHex(hash.getBytes())); - log.error("SATOCHIP PSBTInput verifySignatures error: tapKeyPathSignature: " + Utils.bytesToHex(tapKeyPathSignature.encodeToBitcoin())); - log.error("SATOCHIP PSBTInput verifySignatures error: getUtxo().getScript(): " + getUtxo().getScript()); - log.error("SATOCHIP PSBTInput verifySignatures error: getUtxo(): " + getUtxo()); - log.error("SATOCHIP PSBTInput verifySignatures error: getUtxo().getHash(): " + getUtxo().getHash()); - log.error("SATOCHIP PSBTInput verifySignatures error: getUtxo().getIndex(): " + getUtxo().getIndex()); throw new PSBTSignatureException("Tweaked internal key does not verify against provided taproot keypath signature"); } } else { From 2c2db1d644acc33568635ee5dea3bca319427ed3 Mon Sep 17 00:00:00 2001 From: Toporin Date: Wed, 6 Sep 2023 10:18:32 +0100 Subject: [PATCH 3/4] Clean code and remove debug logs from ECKey.java --- .../sparrowwallet/drongo/crypto/ECKey.java | 94 ++----------------- 1 file changed, 8 insertions(+), 86 deletions(-) diff --git a/src/main/java/com/sparrowwallet/drongo/crypto/ECKey.java b/src/main/java/com/sparrowwallet/drongo/crypto/ECKey.java index 5b6fe67..f6336ab 100644 --- a/src/main/java/com/sparrowwallet/drongo/crypto/ECKey.java +++ b/src/main/java/com/sparrowwallet/drongo/crypto/ECKey.java @@ -307,7 +307,9 @@ public class ECKey { return pub.getEncoded(); } - // SATOCHIP + /** + * Gets the raw public key value in compressed or uncompressed form. This is needed by Satochip + */ public byte[] getPubKey(Boolean compressed) { return pub.getEncoded(compressed); } @@ -433,39 +435,17 @@ public class ECKey { return verify(sigHash.getBytes(), signature); } - - public ECKey getTweakedOutputKey() { - log.debug("SATOCHIP ECKey getTweakedOutputKey START"); + public ECKey getTweakedOutputKeyNEW() { TaprootPubKey taprootPubKey = liftX(getPubKeyXCoord()); - log.debug("SATOCHIP ECKey getTweakedOutputKey taprootPubKey: " + taprootPubKey); - log.debug("SATOCHIP ECKey getTweakedOutputKey taprootPubKey.ecPoint: " + taprootPubKey.ecPoint); ECPoint internalKey = taprootPubKey.ecPoint; - log.debug("SATOCHIP ECKey getTweakedOutputKey internalKey: " + internalKey); - //debug - ECKey tmp2 = ECKey.fromPublicOnly(internalKey, true); - log.debug("SATOCHIP ECKey getTweakedOutputKey internalKey: " + Utils.bytesToHex(tmp2.getPubKey())); - //endbug - byte[] taggedHash = Utils.taggedHash("TapTweak", internalKey.getXCoord().getEncoded()); ECKey tweakValue = ECKey.fromPrivate(taggedHash); - log.debug("SATOCHIP ECKey getTweakedOutputKey tweakValue: " + Utils.bytesToHex(tweakValue.getPubKey())); ECPoint outputKey = internalKey.add(tweakValue.getPubKeyPoint()); - log.debug("SATOCHIP ECKey getTweakedOutputKey outputKey: " + outputKey); - - //debug - ECKey tmp = ECKey.fromPublicOnly(outputKey, true); - log.debug("SATOCHIP ECKey getTweakedOutputKey outputKey: " + Utils.bytesToHex(tmp.getPubKey())); - //endbug - if(hasPrivKey()) { - log.debug("SATOCHIP ECKey getTweakedOutputKey PRIVKEY NEW VERSION"); - // isEven => used to determine private key for tweaking + // see taproot_tweak_seckey(seckey0, h) in + // https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki#constructing-and-spending-taproot-outputs Boolean isEven = (getPubKey()[0] == 0x02); - log.debug("SATOCHIP ECKey getTweakedOutputKey getPubKey(): " + Utils.bytesToHex(getPubKey())); - log.debug("SATOCHIP ECKey getTweakedOutputKey isEven getPubKey()[0]: " + getPubKey()[0]); - log.debug("SATOCHIP ECKey getTweakedOutputKey isEven: " + isEven); - BigInteger taprootPriv; if (isEven){ taprootPriv = priv; @@ -473,79 +453,21 @@ public class ECKey { taprootPriv = CURVE_PARAMS.getCurve().getOrder().subtract(priv); } BigInteger tweakedPrivKey = taprootPriv.add(tweakValue.getPrivKey()).mod(CURVE_PARAMS.getCurve().getOrder()); - - //debug - ECKey tmp3 = new ECKey(tweakedPrivKey, outputKey, true); - log.debug("SATOCHIP ECKey getTweakedOutputKey outputKey with private: " + Utils.bytesToHex(tmp3.getPubKey())); - log.debug("SATOCHIP ECKey getTweakedOutputKey outputKey private: " + tmp3.getPrivKey()); - //endbug - - -/* log.debug("SATOCHIP ECKey getTweakedOutputKey PRIVKEY NEW VERSION SWITCH EVENNESS"); - if (isEven){ - //taprootPriv = priv; - taprootPriv = CURVE_PARAMS.getCurve().getOrder().subtract(priv); - } else { - taprootPriv = priv; - //taprootPriv = CURVE_PARAMS.getCurve().getOrder().subtract(priv); - } - tweakedPrivKey = taprootPriv.add(tweakValue.getPrivKey()).mod(CURVE_PARAMS.getCurve().getOrder()); - - //debug - ECKey tmp5 = new ECKey(tweakedPrivKey, outputKey, true); - log.debug("SATOCHIP ECKey getTweakedOutputKey outputKey with private: " + Utils.bytesToHex(tmp5.getPubKey())); - log.debug("SATOCHIP ECKey getTweakedOutputKey outputKey private: " + tmp5.getPrivKey()); - //endbug*/ - - -/* // ORIGNAL VERSION - log.debug("SATOCHIP ECKey getTweakedOutputKey PRIVKEY OLD VERSION"); - taprootPriv = priv; - 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()); - } - //debug - ECKey tmp4 = new ECKey(tweakedPrivKey, outputKey, true); - log.debug("SATOCHIP ECKey getTweakedOutputKey outputKey with private: " + Utils.bytesToHex(tmp4.getPubKey())); - log.debug("SATOCHIP ECKey getTweakedOutputKey outputKey private: " + tmp4.getPrivKey()); - //endbug*/ - - + return new ECKey(tweakedPrivKey, outputKey, true); } return ECKey.fromPublicOnly(outputKey, true); } - - public ECKey getTweakedOutputKeyOLD() { - log.debug("SATOCHIP ECKey getTweakedOutputKey START"); + public ECKey getTweakedOutputKey() { TaprootPubKey taprootPubKey = liftX(getPubKeyXCoord()); - log.debug("SATOCHIP ECKey getTweakedOutputKey taprootPubKey: " + taprootPubKey); - log.debug("SATOCHIP ECKey getTweakedOutputKey taprootPubKey.ecPoint: " + taprootPubKey.ecPoint); ECPoint internalKey = taprootPubKey.ecPoint; - log.debug("SATOCHIP ECKey getTweakedOutputKey internalKey: " + internalKey); - //debug - ECKey tmp2 = ECKey.fromPublicOnly(internalKey, true); - log.debug("SATOCHIP ECKey getTweakedOutputKey outputKey: " + Utils.bytesToHex(tmp2.getPubKey())); - //endbug - byte[] taggedHash = Utils.taggedHash("TapTweak", internalKey.getXCoord().getEncoded()); ECKey tweakValue = ECKey.fromPrivate(taggedHash); - log.debug("SATOCHIP ECKey getTweakedOutputKey tweakValue: " + Utils.bytesToHex(tweakValue.getPubKey())); ECPoint outputKey = internalKey.add(tweakValue.getPubKeyPoint()); - log.debug("SATOCHIP ECKey getTweakedOutputKey outputKey: " + outputKey); - - //debug - ECKey tmp = ECKey.fromPublicOnly(outputKey, true); - log.debug("SATOCHIP ECKey getTweakedOutputKey outputKey: " + Utils.bytesToHex(tmp.getPubKey())); - //endbug if(hasPrivKey()) { - log.debug("SATOCHIP ECKey getTweakedOutputKey hasPrivKey(): true"); 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? From 83d9dde1323f92d35a6a5ad75440e94639082ea8 Mon Sep 17 00:00:00 2001 From: Toporin Date: Wed, 6 Sep 2023 11:35:35 +0100 Subject: [PATCH 4/4] remove getTweakedOutputKeyNEW() --- .../sparrowwallet/drongo/crypto/ECKey.java | 25 ------------------- 1 file changed, 25 deletions(-) diff --git a/src/main/java/com/sparrowwallet/drongo/crypto/ECKey.java b/src/main/java/com/sparrowwallet/drongo/crypto/ECKey.java index f6336ab..2425adc 100644 --- a/src/main/java/com/sparrowwallet/drongo/crypto/ECKey.java +++ b/src/main/java/com/sparrowwallet/drongo/crypto/ECKey.java @@ -435,31 +435,6 @@ public class ECKey { return verify(sigHash.getBytes(), signature); } - public ECKey getTweakedOutputKeyNEW() { - 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()) { - // isEven => used to determine private key for tweaking - // see taproot_tweak_seckey(seckey0, h) in - // https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki#constructing-and-spending-taproot-outputs - Boolean isEven = (getPubKey()[0] == 0x02); - BigInteger taprootPriv; - if (isEven){ - taprootPriv = priv; - } else { - taprootPriv = CURVE_PARAMS.getCurve().getOrder().subtract(priv); - } - BigInteger tweakedPrivKey = taprootPriv.add(tweakValue.getPrivKey()).mod(CURVE_PARAMS.getCurve().getOrder()); - - return new ECKey(tweakedPrivKey, outputKey, true); - } - - return ECKey.fromPublicOnly(outputKey, true); - } - public ECKey getTweakedOutputKey() { TaprootPubKey taprootPubKey = liftX(getPubKeyXCoord()); ECPoint internalKey = taprootPubKey.ecPoint;