示例#1
0
        /// <summary>
        ///     Recreates the private key of the parent from the private key of the child
        ///     combinated with the public key of the parent (hardened children cannot be
        ///     used to recreate the parent).
        /// </summary>
        public ExtKey GetParentExtKey(ExtPubKey parent)
        {
            if (parent == null)
            {
                throw new ArgumentNullException(nameof(parent));
            }

            if (Depth == 0)
            {
                throw new InvalidOperationException("This ExtKey is the root key of the HD tree");
            }

            if (IsHardened)
            {
                throw new InvalidOperationException("This private key is hardened, so you can't get its parent");
            }

            var expectedFingerPrint = parent.CalculateChildFingerprint();

            if (parent.Depth != Depth - 1 || !expectedFingerPrint.SequenceEqual(_vchFingerprint))
            {
                throw new ArgumentException("The parent ExtPubKey is not the immediate parent of this ExtKey",
                                            nameof(parent));
            }

            byte[] l  = null;
            var    ll = new byte[32];
            var    lr = new byte[32];

            var pubKey = parent.PubKey.ToBytes();

            l = Hashes.BIP32Hash(parent._vchChainCode, _nChild, pubKey[0], pubKey.SafeSubArray(1));
            Array.Copy(l, ll, 32);
            Array.Copy(l, 32, lr, 0, 32);
            var ccChild = lr;

            var parse256LL = new BigInteger(1, ll);
            var N          = ECKey.Curve.N;

            if (!ccChild.SequenceEqual(_vchChainCode))
            {
                throw new InvalidOperationException(
                          "The derived chain code of the parent is not equal to this child chain code");
            }

            var keyBytes = PrivateKey.ToBytes();
            var key      = new BigInteger(1, keyBytes);

            var kPar           = key.Add(parse256LL.Negate()).Mod(N);
            var keyParentBytes = kPar.ToByteArrayUnsigned();

            if (keyParentBytes.Length < 32)
            {
                keyParentBytes = new byte[32 - keyParentBytes.Length].Concat(keyParentBytes).ToArray();
            }

            var parentExtKey = new ExtKey
            {
                _vchChainCode   = parent._vchChainCode,
                _nDepth         = parent.Depth,
                _vchFingerprint = parent.Fingerprint,
                _nChild         = parent._nChild,
                _key            = new Key(keyParentBytes)
            };

            return(parentExtKey);
        }
示例#2
0
 /// <summary>
 ///     Constructor. Creates a representation of an extended key, within the specified network.
 /// </summary>
 public BitcoinExtKey(ExtKey key, Network network)
     : base(key, network)
 {
 }
示例#3
0
 public bool IsParentOf(ExtKey childKey)
 {
     return(childKey.IsChildOf(this));
 }