public static UInt512 HmacSha512(this ReadOnlyByteSpan key, ReadOnlyByteSequence data) { var hash = new UInt512(); new HMACSHA512(key).TransformFinalBlock(data, hash.Span); return(hash); }
public static UInt512 Sha512(this ReadOnlyByteSpan data) { var hash = new UInt512(); Sha512(data, hash.Span); return(hash); }
/// <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); }
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); } }
public static void CopyTo(this byte[] source, ref UInt512 destination) { ((ReadOnlyByteSpan)source).CopyTo(destination.Span); }
/// <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)); }
/// <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);
public IBitcoinWriter Add(UInt512 v) { _alg.TransformBlock(v.Span); return(this); }
public IBitcoinWriter Add(UInt512 v) { Length += UInt256.Length; return(this); }