2 * Novacoin classes library
3 * Copyright (C) 2015 Alex D. (balthazar.ad@gmail.com)
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU Affero General Public License as
7 * published by the Free Software Foundation, either version 3 of the
8 * License, or (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU Affero General Public License for more details.
15 * You should have received a copy of the GNU Affero General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
21 using System.Security.Cryptography;
25 public class CryptoUtils
27 private static SHA1Managed _sha1 = new SHA1Managed();
28 private static SHA256Managed _sha256 = new SHA256Managed();
29 private static RIPEMD160Managed _ripe160 = new RIPEMD160Managed();
34 /// <param name="inputBytes">Bytes to hash</param>
35 /// <returns>Hashing result</returns>
36 public static byte[] ComputeSha1(byte[] inputBytes)
38 return _sha1.ComputeHash(inputBytes, 0, inputBytes.Length);
42 /// Sha256 calculation
44 /// <param name="inputBytes">Bytes to hash</param>
45 /// <returns>Hashing result</returns>
46 public static byte[] ComputeSha256(byte[] inputBytes)
48 return _sha256.ComputeHash(inputBytes, 0, inputBytes.Length);
52 /// RIPEMD-160 calculation
54 /// <param name="inputBytes">Bytes to hash</param>
55 /// <returns>Hashing result</returns>
56 public static byte[] ComputeRipeMD160(byte[] inputBytes)
58 return _ripe160.ComputeHash(inputBytes, 0, inputBytes.Length);
62 /// RipeMD160(Sha256(X)) calculation
64 /// <param name="inputBytes">Bytes to hash</param>
65 /// <returns>Hashing result</returns>
66 public static byte[] ComputeHash160(byte[] inputBytes)
68 var digest1 = _sha256.ComputeHash(inputBytes, 0, inputBytes.Length);
69 return _ripe160.ComputeHash(digest1, 0, digest1.Length);
73 /// Sha256(Sha256(X)) calculation
75 /// <param name="inputBytes">Bytes to hash</param>
76 /// <returns>Hashing result</returns>
77 public static byte[] ComputeHash256(byte[] dataBytes)
79 var digest1 = _sha256.ComputeHash(dataBytes, 0, dataBytes.Length);
80 return _sha256.ComputeHash(digest1, 0, digest1.Length);
84 /// Sha256(Sha256(X)) calculation
86 /// <param name="input1">Reference to first half of data</param>
87 /// <param name="input2">Reference to second half of data</param>
88 /// <returns>Hashing result</returns>
89 public static byte[] ComputeHash256(ref byte[] input1, ref byte[] input2)
91 var buffer = new byte[64];
93 input1.CopyTo(buffer, 0);
94 input2.CopyTo(buffer, input1.Length);
96 var digest1 = _sha256.ComputeHash(buffer, 0, buffer.Length);
97 return _sha256.ComputeHash(digest1, 0, digest1.Length);
100 public static byte[] PBKDF2_Sha256(int dklen, byte[] password, byte[] salt, int iterationCount)
102 /* Init HMAC state. */
103 using (var hmac = new HMACSHA256(password))
105 int hashLength = hmac.HashSize / 8;
106 if ((hmac.HashSize & 7) != 0)
110 int keyLength = dklen / hashLength;
111 if (dklen > (0xFFFFFFFFL * hashLength) || dklen < 0)
113 throw new ArgumentOutOfRangeException("dklen");
115 if (dklen % hashLength != 0)
119 var extendedkey = new byte[salt.Length + 4];
120 Buffer.BlockCopy(salt, 0, extendedkey, 0, salt.Length);
121 using (var ms = new MemoryStream())
123 /* Iterate through the blocks. */
124 for (int i = 0; i < keyLength; i++)
126 /* Generate INT(i + 1). */
127 extendedkey[salt.Length] = (byte)(((i + 1) >> 24) & 0xFF);
128 extendedkey[salt.Length + 1] = (byte)(((i + 1) >> 16) & 0xFF);
129 extendedkey[salt.Length + 2] = (byte)(((i + 1) >> 8) & 0xFF);
130 extendedkey[salt.Length + 3] = (byte)(((i + 1)) & 0xFF);
132 /* Compute U_1 = PRF(P, S || INT(i)). */
133 var u = hmac.ComputeHash(extendedkey);
134 Array.Clear(extendedkey, salt.Length, 4);
138 for (int j = 1; j < iterationCount; j++)
141 u = hmac.ComputeHash(u);
142 for (int k = 0; k < f.Length; k++)
144 /* ... xor U_j ... */
149 /* Copy as many bytes as necessary into memory stream. */
150 ms.Write(f, 0, f.Length);
151 Array.Clear(u, 0, u.Length);
152 Array.Clear(f, 0, f.Length);
156 /* Initialize result array. */
157 var dk = new byte[dklen];
159 /* Read key from memory stream. */
160 ms.Read(dk, 0, dklen);
163 for (long i = 0; i < ms.Length; i++)
167 Array.Clear(extendedkey, 0, extendedkey.Length);