Esempio n. 1
0
 private TaprootFullPubKey(ECXOnlyPubKey outputKey, bool outputParity, TaprootInternalPubKey internalKey, uint256?merkleRoot) : base(outputKey)
 {
     OutputKey       = new TaprootPubKey(outputKey);
     OutputKeyParity = outputParity;
     InternalKey     = internalKey;
     MerkleRoot      = merkleRoot;
 }
 public static bool TryCreate(ReadOnlySpan <byte> pubkey, [MaybeNullWhen(false)] out TaprootInternalPubKey result)
 {
     if (ECXOnlyPubKey.TryCreate(pubkey, out var k))
     {
         result = new TaprootInternalPubKey(k);
         return(true);
     }
     result = null;
     return(false);
 }
        public bool CheckTapTweak(TaprootInternalPubKey internalPubKey, uint256?merkleRoot, bool parity)
        {
            if (internalPubKey is null)
            {
                throw new ArgumentNullException(nameof(internalPubKey));
            }

            Span <byte> tweak32 = stackalloc byte[32];

            TaprootFullPubKey.ComputeTapTweak(internalPubKey, merkleRoot, tweak32);
            return(this.pubkey.CheckIsTweakedWith(internalPubKey.pubkey, tweak32, parity));
        }
Esempio n. 4
0
 internal static void ComputeTapTweak(TaprootInternalPubKey internalKey, uint256?merkleRoot, Span <byte> tweak32)
 {
     using Secp256k1.SHA256 sha = new Secp256k1.SHA256();
     sha.InitializeTagged("TapTweak");
     internalKey.pubkey.WriteToSpan(tweak32);
     sha.Write(tweak32);
     if (merkleRoot is uint256)
     {
         merkleRoot.ToBytes(tweak32);
         sha.Write(tweak32);
     }
     sha.GetHash(tweak32);
 }
Esempio n. 5
0
        public static TaprootFullPubKey Create(TaprootInternalPubKey internalKey, uint256?merkleRoot)
        {
            if (internalKey is null)
            {
                throw new ArgumentNullException(nameof(internalKey));
            }
            Span <byte> tweak32 = stackalloc byte[32];

            ComputeTapTweak(internalKey, merkleRoot, tweak32);
            var outputKey = internalKey.pubkey.AddTweak(tweak32).ToXOnlyPubKey(out var parity);

            return(new TaprootFullPubKey(outputKey, parity, internalKey, merkleRoot));
        }
        public static bool TryCreate(byte[] pubkey, [MaybeNullWhen(false)] out TaprootInternalPubKey result)
        {
#if HAS_SPAN
            return(TryCreate(pubkey.AsSpan(), out result));
#else
            if (pubkey.Length != 32)
            {
                result = null;
                return(false);
            }
            result = new TaprootInternalPubKey(pubkey);
            return(true);
#endif
        }
 public int CompareTo(TaprootInternalPubKey other)
 {
     return(BytesComparer.Instance.Compare(this.pubkey, other.pubkey));
 }
 public int CompareTo(TaprootInternalPubKey other)
 {
     return(this.pubkey.CompareTo(other.pubkey));
 }
Esempio n. 9
0
 public bool CheckTapTweak(TaprootInternalPubKey internalPubKey)
 {
     return(this.CheckTapTweak(internalPubKey, MerkleRoot, OutputKeyParity));
 }
Esempio n. 10
0
        internal PSBTOutput(BitcoinStream stream, PSBT parent, uint index, TxOut txOut) : base(parent)
        {
            if (txOut == null)
            {
                throw new ArgumentNullException(nameof(txOut));
            }
            if (parent == null)
            {
                throw new ArgumentNullException(nameof(parent));
            }

            TxOut = txOut;
            Index = index;

            byte[] k = new byte[0];
            byte[] v = new byte[0];
            try
            {
                stream.ReadWriteAsVarString(ref k);
            }
            catch (EndOfStreamException e)
            {
                throw new FormatException("Invalid PSBTOutput. Could not read key", e);
            }
            while (k.Length != 0)
            {
                try
                {
                    stream.ReadWriteAsVarString(ref v);
                }
                catch (EndOfStreamException e)
                {
                    throw new FormatException("Invalid PSBTOutput. Could not read value", e);
                }
                switch (k.First())
                {
                case PSBTConstants.PSBT_OUT_REDEEMSCRIPT:
                    if (k.Length != 1)
                    {
                        throw new FormatException("Invalid PSBTOutput. Contains illegal value in key for redeem script");
                    }
                    if (redeem_script != null)
                    {
                        throw new FormatException("Invalid PSBTOutput, duplicate key for redeem_script");
                    }
                    redeem_script = Script.FromBytesUnsafe(v);
                    break;

                case PSBTConstants.PSBT_OUT_WITNESSSCRIPT:
                    if (k.Length != 1)
                    {
                        throw new FormatException("Invalid PSBTOutput. Unexpected key length for PSBT_OUT_BIP32_DERIVATION");
                    }
                    if (witness_script != null)
                    {
                        throw new FormatException("Invalid PSBTOutput, duplicate key for redeem_script");
                    }
                    witness_script = Script.FromBytesUnsafe(v);
                    break;

                case PSBTConstants.PSBT_OUT_BIP32_DERIVATION:
                    var pubkey2 = new PubKey(k.Skip(1).ToArray());
                    if (hd_keypaths.ContainsKey(pubkey2))
                    {
                        throw new FormatException("Invalid PSBTOutput, duplicate key for hd_keypaths");
                    }
                    KeyPath path = KeyPath.FromBytes(v.Skip(4).ToArray());
                    hd_keypaths.Add(pubkey2, new RootedKeyPath(new HDFingerprint(v.Take(4).ToArray()), path));
                    break;

                case PSBTConstants.PSBT_OUT_TAP_BIP32_DERIVATION:
                    var pubkey3 = new TaprootPubKey(k.Skip(1).ToArray());
                    if (hd_taprootkeypaths.ContainsKey(pubkey3))
                    {
                        throw new FormatException("Invalid PSBTOutput, duplicate key for hd_taproot_keypaths");
                    }
                    var            bs     = new BitcoinStream(v);
                    List <uint256> hashes = null !;
                    bs.ReadWrite(ref hashes);
                    var     pos   = (int)bs.Inner.Position;
                    KeyPath path2 = KeyPath.FromBytes(v.Skip(pos + 4).ToArray());
                    hd_taprootkeypaths.Add(pubkey3,
                                           new TaprootKeyPath(
                                               new RootedKeyPath(new HDFingerprint(v.Skip(pos).Take(4).ToArray()), path2),
                                               hashes.ToArray()));
                    break;

                case PSBTConstants.PSBT_OUT_TAP_INTERNAL_KEY:
                    if (k.Length != 1)
                    {
                        throw new FormatException("Invalid PSBTOutput. Contains illegal value in key for internal taproot pubkey");
                    }
                    if (!TaprootInternalPubKey.TryCreate(v, out var tpk))
                    {
                        throw new FormatException("Invalid PSBTOutput. Contains invalid internal taproot pubkey");
                    }
                    TaprootInternalKey = tpk;
                    break;

                default:
                    if (unknown.ContainsKey(k))
                    {
                        throw new FormatException("Invalid PSBTInput, duplicate key for unknown value");
                    }
                    unknown.Add(k, v);
                    break;
                }
                stream.ReadWriteAsVarString(ref k);
            }
        }