public static UInt512 HmacSha512(this ReadOnlyByteSpan key, ReadOnlyByteSequence data)
        {
            var hash = new UInt512();

            new HMACSHA512(key).TransformFinalBlock(data, hash.Span);
            return(hash);
        }
Ejemplo n.º 2
0
        public static UInt512 Sha512(this ReadOnlyByteSpan data)
        {
            var hash = new UInt512();

            Sha512(data, hash.Span);
            return(hash);
        }
Ejemplo n.º 3
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);
        }
Ejemplo n.º 4
0
 public void TestCases()
 {
     foreach (var tv in _testValues)
     {
         tv.Entropy.HexToBytes();
         var mnemonic = new Mnemonic(tv.Words, Languages.English);
         Assert.NotNull(mnemonic); // If checksum doesn't match returns null.
         var seed      = new UInt512(tv.Seed, true);
         var seedBip39 = ExtPrivateKey.Bip39Seed(tv.Words, "TREZOR");
         Assert.Equal(seed, seedBip39);
         var privkeyFromWords = ExtPrivateKey.MasterBip39(tv.Words, "TREZOR");
         var privkeyFromB58   = new Base58ExtPrivateKey(tv.B58Priv).GetKey();
         Assert.Equal(privkeyFromB58, privkeyFromWords);
     }
 }
Ejemplo n.º 5
0
 public static void CopyTo(this byte[] source, ref UInt512 destination)
 {
     ((ReadOnlyByteSpan)source).CopyTo(destination.Span);
 }
Ejemplo n.º 6
0
 /// <summary>
 /// Sets this extended private key to be a master (depth 0) with the private key and chaincode set from the single 512 bit vout parameter.
 /// Master private key will be set to the first 256 bits.
 /// Chaincode will be set from the last 256 bits.
 /// </summary>
 /// <param name="vout">Master private key will be set to the first 256 bits. Chaincode will be set from the last 256 bits.</param>
 /// <param name="required">if not null, each key path will be verified as valid on the specified key or returns null.</param>
 /// <returns>Returns this key unless required key paths aren't valid for specified key.</returns>
 public ExtPrivateKey SetMaster(UInt512 vout, IEnumerable <KeyPath> required = null)
 {
     return(SetMaster((UInt256)vout.Span.Slice(0, 32), (UInt256)vout.Span.Slice(32, 32), required));
 }
Ejemplo n.º 7
0
 /// <summary>
 /// Returns a new extended private key to be a master (depth 0) with the private key and chaincode set from the single 512 bit vout parameter.
 /// Master private key will be set to the first 256 bits.
 /// Chaincode will be set from the last 256 bits.
 /// </summary>
 /// <param name="vout">Master private key will be set to the first 256 bits. Chaincode will be set from the last 256 bits.</param>
 /// <param name="required">if not null, each key path will be verified as valid on the specified key or returns null.</param>
 /// <returns>Returns new key unless required key paths aren't valid for specified key in which case null is returned.</returns>
 public static ExtPrivateKey Master(UInt512 vout, IEnumerable <KeyPath> required = null)
 => new ExtPrivateKey().SetMaster(vout, required);
Ejemplo n.º 8
0
 public IBitcoinWriter Add(UInt512 v)
 {
     _alg.TransformBlock(v.Span);
     return(this);
 }
Ejemplo n.º 9
0
 public IBitcoinWriter Add(UInt512 v)
 {
     Length += UInt256.Length;
     return(this);
 }