public void ComputeHashTwiceTest(byte[] message, byte[] expectedHash) { using Sha256 sha = new Sha256(); byte[] actualHash = sha.ComputeHashTwice(message); expectedHash = sha.ComputeHash(expectedHash); Assert.Equal(expectedHash, actualHash); }
public void ComputeHash_DoubleTest() { using Sha256 sha = new Sha256(); var data = Helper.HexToBytes("fb8049137747e712628240cf6d7056ea2870170cb7d9bc713d91e901b514c6ae7d7dda3cd03ea1b99cf85046a505f3590541123d3f8f2c22c4d7d6e65de65c4ebb9251f09619"); byte[] actualHash = sha.ComputeHashTwice(data); byte[] expectedHash = Helper.HexToBytes("d2cee8d3cfaf1819c55cce1214d01cdef1d97446719ccfaad4d76d912a8126f9"); Assert.Equal(expectedHash, actualHash); }
/// <summary> /// Decrypts the given base-58 encoded encrypted key using the given password bytes and first 4 bytes of hash of /// (un)compressed P2PKH address as <see cref="Scrypt"/> salt. /// </summary> /// <exception cref="ArgumentNullException"/> /// <exception cref="FormatException"/> /// <exception cref="ObjectDisposedException"/> /// <param name="encrypted">Base-58 encrypted key (it will be normalized using Unicode Normalization Form C (NFC))</param> /// <param name="password">Password to use</param> /// <param name="isCompressed">Indicates whether to use compressed or uncompressed public key to build P2PKH address</param> /// <returns>The private key</returns> public PrivateKey Decrypt(string encrypted, byte[] password, out bool isCompressed) { if (isDisposed) { throw new ObjectDisposedException(nameof(BIP0038), "Instance was disposed."); } if (string.IsNullOrWhiteSpace(encrypted)) { throw new ArgumentNullException(nameof(encrypted), "Invalid (null) encrypted key."); } if (password == null) { throw new ArgumentNullException(nameof(password), "Password can not be null."); } byte[] encryptedBytes = Base58.DecodeWithChecksum(encrypted); if (encryptedBytes.Length != EncodedLength) { throw new FormatException("Invalid encrypted bytes length."); } if (!((Span <byte>)encryptedBytes).Slice(0, 2).SequenceEqual(prefix)) { throw new FormatException("Invalid prefix."); } isCompressed = IsCompressed(encryptedBytes[2]); Span <byte> salt = ((Span <byte>)encryptedBytes).Slice(3, 4); byte[] dk = scrypt.GetBytes(password, salt.ToArray(), 64); byte[] decryptedResult = new byte[32]; aes.Key = dk.SubArray(32, 32); // AES key is derivedhalf2 using ICryptoTransform decryptor = aes.CreateDecryptor(); decryptor.TransformBlock(encryptedBytes, 7, 16, decryptedResult, 0); decryptor.TransformBlock(encryptedBytes, 23, 16, decryptedResult, 16); // XOR method will only work on first item's length (32 byte here) so it doesn't matter of dk.Legth is 64 PrivateKey result = new PrivateKey(XOR(decryptedResult, dk)); string address = Address.GetP2pkh(result.ToPublicKey(), isCompressed, NetworkType.MainNet); Span <byte> computedHash = hash.ComputeHashTwice(Encoding.ASCII.GetBytes(address)).SubArray(0, 4); if (!computedHash.SequenceEqual(salt)) { throw new FormatException("Wrong password (derived address hash is not the same)."); } return(result); }
/// <summary> /// Replaces top stack item with its hash digest. Return value indicates success. /// </summary> /// <param name="opData">Data to use</param> /// <param name="error">Error message (null if sucessful, otherwise will contain information about the failure)</param> /// <returns>True if operation was successful, false if otherwise</returns> public override bool Run(IOpData opData, out string error) { if (opData.ItemCount < 1) { error = Err.OpNotEnoughItems; return(false); } using Sha256 hash = new Sha256(); opData.Push(hash.ComputeHashTwice(opData.Pop())); error = null; return(true); }
/// <summary> /// Returns the 256-bit result of double SHA-256 hash of the message with the added constant used in signing operation. /// </summary> /// <exception cref="ArgumentNullException"/> /// <param name="message"> /// UTF-8 encoded message to sign (will be normalized using full compatibility decomposition form). /// <para/>Note that trailing spaces, new line character,... will not be changed here. /// Caller has to decide whether to change those /// </param> /// <returns>256-bit hash</returns> public byte[] GetBytesToSign(string message) { if (message is null) { throw new ArgumentNullException(nameof(message), "Message can not be null."); } using Sha256 hash = new Sha256(); FastStream stream = new FastStream(); stream.Write((byte)Constants.MsgSignConst.Length); stream.Write(Encoding.UTF8.GetBytes(Constants.MsgSignConst)); byte[] messageBytes = Encoding.UTF8.GetBytes(message.Normalize(NormalizationForm.FormKD)); stream.WriteWithCompactIntLength(messageBytes); byte[] result = hash.ComputeHashTwice(stream.ToByteArray()); return(result); }
private bool CheckMessage(string message, out byte[] toSign) { try { FastStream stream = new FastStream(); byte[] msgBa = Encoding.UTF8.GetBytes(message); stream.Write((byte)Constants.MsgSignConst.Length); stream.Write(Encoding.UTF8.GetBytes(Constants.MsgSignConst)); new CompactInt((ulong)msgBa.Length).WriteToStream(stream); stream.Write(msgBa); using Sha256 hash = new Sha256(); toSign = hash.ComputeHashTwice(stream.ToByteArray()); return(true); } catch (Exception) { toSign = null; return(false); } }
public byte[] Library_Sha256d(byte[] data) => libSha.ComputeHashTwice(data);