Exemple #1
0
 protected void SetData(ReadOnlyByteSpan version, ReadOnlyByteSpan data, bool flag = false)
 {
     _versionData   = new byte[version.Length + data.Length + 1];
     _versionLength = version.Length;
     version.CopyTo(Version);
     data.CopyTo(KeyData);
     KeyData.Data[^ 1] = (byte)(flag ? 1 : 0);
Exemple #2
0
        /// <summary>
        /// Duplicates Python hash library pbkdf2_hmac for hash_name = 'sha512' and dklen = None
        ///
        /// Performance can be improved by pre-computing _trans_36 and _trans_5c.
        /// Unlike Python's hash functions, .NET doesn't currently support copying state between blocks.
        /// This results in having to recompute hash of innerSeed and outerSeed on each iteration.
        /// </summary>
        /// <param name="password"></param>
        /// <param name="salt"></param>
        /// <param name="iterations"></param>
        /// <returns></returns>
        public static UInt512 PbKdf2HmacSha512(ReadOnlyByteSpan password, ReadOnlyByteSpan salt, int iterations)
        {
            if (iterations < 1)
            {
                throw new ArgumentException();
            }

            byte[] passwordBytes = password;

            using var inner = new SHA512Managed();
            using var outer = new SHA512Managed();

            const int blocksize = 128; // match python hash library sha512 block size.

            if (passwordBytes.Length > blocksize)
            {
                inner.TransformFinalBlock(passwordBytes, 0, passwordBytes.Length);
                passwordBytes = inner.Hash;
                //inner.Initialize();
            }

            if (passwordBytes.Length < blocksize)
            {
                Array.Resize(ref passwordBytes, blocksize);
            }

            var trans36 = new byte[256];
            var trans5C = new byte[256];

            for (var i = 0; i < 256; i++)
            {
                trans36[i] = (byte)(i ^ 0x36);
                trans5C[i] = (byte)(i ^ 0x5c);
            }

            var innerSeed = passwordBytes.Select(pb => trans36[pb]).ToArray();
            var outerSeed = passwordBytes.Select(pb => trans5C[pb]).ToArray();

            var hash  = new UInt512();
            var xhash = new UInt512();

            var data = new byte[salt.Length + 4];

            salt.CopyTo(data);
            1.AsReadOnlySpan(bigEndian: true).CopyTo(data.AsSpan(salt.Length));
            var dataSpan = data.AsSpan();

            for (var i = 0; i < iterations; i++)
            {
                inner.TransformBlock(innerSeed);
                outer.TransformBlock(outerSeed);
                inner.TransformFinalBlock(dataSpan, hash.Span);
                outer.TransformFinalBlock(hash.Span, hash.Span);
                dataSpan = hash.Span;
                xhash    = i == 0 ? hash : xhash ^ hash;
            }

            return(xhash);
        }
Exemple #3
0
        public string Encode(ReadOnlyByteSpan data1, ReadOnlyByteSpan data2)
        {
            var bytes = new byte[data1.Length + data2.Length].AsSpan();

            data1.CopyTo(bytes);
            data2.CopyTo(bytes.Slice(data1.Length));
            return(Encode(bytes));
        }
        /// <summary>
        /// Appends first 4 bytes of double SHA256 hash to bytes before standard Base58 encoding.
        /// </summary>
        /// <param name="bytes"></param>
        /// <returns></returns>
        public override string Encode(ReadOnlyByteSpan bytes)
        {
            var checksum = bytes.Hash256();
            var buf      = new byte[bytes.Length + 4];

            bytes.CopyTo(buf);
            checksum.Span.Slice(0, 4).CopyTo(buf.AsSpan().Slice(bytes.Length));
            return(Encoders.Base58.Encode(buf));
        }
Exemple #5
0
 public PublicKey(ReadOnlyByteSpan bytes)
     : this()
 {
     if (bytes.Length > 0 && bytes.Length == PredictLength(bytes[0]))
     {
         _bytes = new byte[bytes.Length];
         bytes.CopyTo(_bytes);
     }
 }
Exemple #6
0
 internal void Set(ReadOnlyByteSpan data, bool compressed = true)
 {
     if (data.Length != UInt256.Length || !Check(data))
     {
         IsValid = false;
     }
     else
     {
         data.CopyTo(_keyData.Span);
         IsCompressed = compressed;
         IsValid      = true;
     }
 }
Exemple #7
0
        public void Set(ReadOnlyByteSpan data)
        {
            var len = data.Length == 0 ? 0 : PredictLength(data[0]);

            if (len > 0 && len == data.Length)
            {
                _bytes = new byte[data.Length];
                data.CopyTo(_bytes.AsSpan());
            }
            else
            {
                Invalidate();
            }
        }
Exemple #8
0
        /// <summary>
        /// Hash used to implement BIP 32 key derivations.
        /// </summary>
        /// <param name="chainCode"></param>
        /// <param name="nChild"></param>
        /// <param name="header"></param>
        /// <param name="data"></param>
        /// <param name="output">512 bit, 64 byte hash.</param>
        public static void Bip32Hash(UInt256 chainCode, uint nChild, byte header, ReadOnlyByteSpan data, ByteSpan output)
        {
            var len = data.Length;
            var buf = new byte[1 + len + 4]; // header, data, nChild
            var s   = buf.AsSpan();

            s[0] = header;
            data.CopyTo(s.Slice(1, len));
            var num = s.Slice(1 + len, 4);

            num[0] = (byte)((nChild >> 24) & 0xFF);
            num[1] = (byte)((nChild >> 16) & 0xFF);
            num[2] = (byte)((nChild >> 8) & 0xFF);
            // ReSharper disable once ShiftExpressionRealShiftCountIsZero
            num[3] = (byte)((nChild >> 0) & 0xFF);

            HmacSha512(chainCode.Span, s, output);
        }