Beispiel #1
0
 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);
 }
Beispiel #2
0
        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);
        }
Beispiel #3
0
        /// <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);
        }
Beispiel #4
0
        /// <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);
        }
Beispiel #5
0
        /// <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);
            }
        }
Beispiel #7
0
 public byte[] Library_Sha256d(byte[] data) => libSha.ComputeHashTwice(data);