示例#1
0
        public static string PublicKeyToAddress(byte[] publicKey, int networkPrefix)
        {
            KeccakDigest shaDigest = new KeccakDigest(256);

            byte[] bytesFirst = new byte[32];

            shaDigest.BlockUpdate(publicKey, 0, 32);
            shaDigest.DoFinal(bytesFirst, 0);

            RipeMD160Digest digestRipeMd160 = new RipeMD160Digest();

            byte[] bytesSecond = new byte[20];

            digestRipeMd160.BlockUpdate(bytesFirst, 0, 32);
            digestRipeMd160.DoFinal(bytesSecond, 0);

            byte[] bytesThird = CryptoBytes.FromHexString(
                string.Concat(networkPrefix,
                              CryptoBytes.ToHexStringLower(bytesSecond))
                );

            byte[] bytesFourth = new byte[32];

            shaDigest.BlockUpdate(bytesThird, 0, 21);
            shaDigest.DoFinal(bytesFourth, 0);

            byte[] bytesFifth = new byte[4];
            Array.Copy(bytesFourth, 0, bytesFifth, 0, 4);

            byte[] bytesSixth = new byte[25];
            Array.Copy(bytesThird, 0, bytesSixth, 0, 21);
            Array.Copy(bytesFifth, 0, bytesSixth, 21, 4);

            return(Base32.Encode(bytesSixth).ToUpper());
        }
示例#2
0
        internal static byte[] DerivePassSha(string password, int count)
        {
            if (password == null)
            {
                throw new ArgumentNullException(nameof(password));
            }
            if (count <= 0)
            {
                throw new ArgumentOutOfRangeException(nameof(count), "must be positive");
            }

            var sha3Hasher = new KeccakDigest(256);
            var priv       = new byte[32];


            sha3Hasher.BlockUpdate(Encoding.UTF8.GetBytes(password), 0, password.Length);
            sha3Hasher.DoFinal(priv, 0);

            for (var i = 0; i < count - 1; ++i)
            {
                sha3Hasher.Reset();
                sha3Hasher.BlockUpdate(priv, 0, priv.Length);
                sha3Hasher.DoFinal(priv, 0);
            }

            return(priv);
        }
        /// <summary>
        ///     Derive a private key from a password using count iterations of SHA3-256
        /// </summary>
        /// <param name="password">The password.</param>
        /// <param name="count">The count.</param>
        /// <returns>System.String.</returns>
        /// <exception cref="ArgumentNullException">password</exception>
        /// <exception cref="ArgumentOutOfRangeException">count - must be positive</exception>
        internal static string DerivePassSha(byte[] password, int count)
        {
            if (password == null)
            {
                throw new ArgumentNullException(nameof(password));
            }
            if (count <= 0)
            {
                throw new ArgumentOutOfRangeException(nameof(count), "must be positive");
            }

            var sha3Hasher = new KeccakDigest(256);
            var hash       = new byte[32];


            sha3Hasher.BlockUpdate(password, 0, password.Length);
            sha3Hasher.DoFinal(hash, 0);

            for (var i = 0; i < count - 1; ++i)
            {
                sha3Hasher.Reset();
                sha3Hasher.BlockUpdate(hash, 0, hash.Length);
                sha3Hasher.DoFinal(hash, 0);
            }

            return(hash.ToHexUpper());
        }
示例#4
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="trits"></param>
        /// <param name="offset"></param>
        /// <param name="length"></param>
        /// <returns></returns>
        public override sbyte[] Squeeze(sbyte[] trits, int offset, int length)
        {
            if (length % 243 != 0)
            {
                throw new IllegalStateException("Illegal length: " + length);
            }

            do
            {
                _keccak.DoFinal(_byteState, 0);

                //convert to trits
                FixedBigIntConverter.FromBytesToTrits(_byteState, _tritState);

                //copy with offset
                _tritState[HASH_LENGTH - 1] = 0;
                Array.Copy(_tritState, 0, trits, offset, HASH_LENGTH);

                //calculate hash again
                for (var i = _byteState.Length; i-- > 0;)
                {
                    _byteState[i] = (byte)(_byteState[i] ^ 0xFF);
                }

                _keccak.BlockUpdate(_byteState, 0, _byteState.Length);
                offset += HASH_LENGTH;
            } while ((length -= HASH_LENGTH) > 0);

            return(trits);
        }
示例#5
0
        public void KeccakDigestTest()
        {
            var ints = new uint[]
            {
                9, 96, 55, 9457, 5, 9, 5, 9, 5, 9, 5, 9
            };

            var bytes = Kerl.ConvertToByteArray(ints);

            var sha3Digest = new KeccakDigest(Kerl.BIT_HASH_LENGTH);

            sha3Digest.BlockUpdate(bytes, 0, bytes.Length);

            var output = new byte[48];
            var count  = sha3Digest.DoFinal(output, 0);

            var result = Kerl.ConvertToInt32Array(output);

            Assert.AreEqual(48, count);
            Assert.AreEqual(-1783424869, result[0]);
            Assert.AreEqual(-1114296599, result[1]);
            Assert.AreEqual(883842121, result[2]);
            Assert.AreEqual(1128053166, result[3]);

            Assert.AreEqual(1941138521, result[4]);
            Assert.AreEqual(545983793, result[5]);
            Assert.AreEqual(1613000376, result[6]);
            Assert.AreEqual(1678837429, result[7]);

            Assert.AreEqual(-1049582418, result[8]);
            Assert.AreEqual(161709750, result[9]);
            Assert.AreEqual(-308485616, result[10]);
            Assert.AreEqual(-139697445, result[11]);
        }
示例#6
0
        /// <inheritdoc />
        /// <summary>
        /// </summary>
        /// <param name="trits"></param>
        /// <param name="offset"></param>
        /// <param name="length"></param>
        /// <returns></returns>
        /// <exception cref="T:Iota.Lib.CSharp.Api.Exception.IllegalStateException"></exception>
        public override void Squeeze(int[] trits, int offset, int length)
        {
            if (length % 243 != 0)
            {
                throw new IllegalStateException("Illegal length: " + length);
            }

            do
            {
                _keccak.DoFinal(_byteState, 0);

                //convert to trits
                FixedBigIntConverter.FromBytesToTrits(_byteState, _tritState);
                //BigIntConverter.TritsFromBigInt(
                //    BigIntConverter.BigIntFromBytes(_byteState, 0, ByteHashLength),
                //    _tritState, 0, HashLength);

                //copy with offset
                _tritState[HashLength - 1] = 0;
                Array.Copy(_tritState, 0, trits, offset, HashLength);

                //calculate hash again
                for (var i = _byteState.Length; i-- > 0;)
                {
                    _byteState[i] = (byte)(_byteState[i] ^ 0xFF);
                }

                _keccak.BlockUpdate(_byteState, 0, _byteState.Length);
                offset += HashLength;
            } while ((length -= HashLength) > 0);
        }
示例#7
0
        static public BigInteger Mine(string challenge, BigInteger difficulty)
        {
            Byte[] b = new Byte[8];

            var sha3 = new KeccakDigest(512);

            var rnd = new Random(0);

            rnd.NextBytes(b);
            b = b.Reverse().Concat(new byte[] { 0x0 }).ToArray();

            var nonce = new BigInteger(b);

            var challengeBI = BigInteger.Parse(challenge, NumberStyles.AllowHexSpecifier);

            while (true)
            {
                byte[] hashb = new byte[sha3.GetDigestSize()];
                byte[] value = challengeBI.ToByteArray().Reverse().Concat(nonce.ToByteArray().Reverse()).ToArray();
                sha3.BlockUpdate(value, 0, value.Length);
                sha3.DoFinal(hashb, 0);

                hashb = hashb.Reverse().Concat(new byte[] { 0x0 }).ToArray();
                var v = new BigInteger(hashb);
                if (v.CompareTo(difficulty) < 0)
                {
                    break;
                }

                nonce = (BigInteger.Add(nonce, BigInteger.One)) % ((new BigInteger(2)) << 64);
            }

            return(nonce);
        }
示例#8
0
        internal static void crypto_sign2(
            byte[] sig,
            byte[] m,
            byte[] sk,
            int keylen)
        {
            byte[]         privHash   = new byte[64];
            byte[]         seededHash = new byte[64];
            byte[]         result     = new byte[64];
            GroupElementP3 R          = new GroupElementP3();
            var            hasher     = new KeccakDigest(512);
            {
                var reversedPrivateKey = new byte[keylen];
                Array.Copy(sk, 0, reversedPrivateKey, 0, keylen);
                Array.Reverse(reversedPrivateKey);

                hasher.BlockUpdate(reversedPrivateKey, 0, keylen);
                hasher.DoFinal(privHash, 0);

                ScalarOperations.sc_clamp(privHash, 0);

                hasher.Reset();
                hasher.BlockUpdate(privHash, 32, 32);
                hasher.BlockUpdate(m, 0, m.Length);
                hasher.DoFinal(seededHash, 0);

                ScalarOperations.sc_reduce(seededHash);

                GroupOperations.ge_scalarmult_base(out R, seededHash, 0);
                GroupOperations.ge_p3_tobytes(sig, 0, ref R);

                hasher.Reset();
                hasher.BlockUpdate(sig, 0, 32);
                hasher.BlockUpdate(sk, keylen, 32);
                hasher.BlockUpdate(m, 0, m.Length);
                hasher.DoFinal(result, 0);

                ScalarOperations.sc_reduce(result);

                var s = new byte[32]; //todo: remove allocation
                Array.Copy(sig, 32, s, 0, 32);
                ScalarOperations.sc_muladd(s, result, privHash, seededHash);
                Array.Copy(s, 0, sig, 32, 32);

                CryptoBytes.Wipe(s);
            }
        }
        /// <summary>
        /// Converts a public key to a main net or test net address. Network byte determines which network version to convert to.
        /// </summary>
        /// <param name="network">The network byte.</param>
        /// <param name="publicKey">The public key.</param>
        /// <returns>The unhyphenated address string.</returns>
        /// <exception cref="ArgumentException">invalid public key. Thrown when a public key is not a 64 char hex string.</exception>
        /// <example>
        /// This sample shows how to use the <see cref="ToEncoded"/> method.
        /// <code>
        /// class TestClass
        /// {
        ///     static void Main()
        ///     {
        ///         Connection connection = new Connection();
        ///
        ///         string address = AddressEncoding.ToEncoded(connection.GetNetworkVersion(), new PublicKey("0705c2634de7e58325dabc58c4a794559be4d55d102d3aafcb189acb2e596add"));
        ///     }
        /// }
        /// </code>
        /// </example>
        public static string ToEncoded(byte network, PublicKey publicKey)
        {
            if (!StringUtils.OnlyHexInString(publicKey.Raw) || publicKey.Raw.Length != 64)
            {
                throw new ArgumentException("invalid public key");
            }

            // step 1) sha-3(256) public key
            var digestSha3 = new KeccakDigest(256);
            var stepOne    = new byte[32];

            digestSha3.BlockUpdate(CryptoBytes.FromHexString(publicKey.Raw), 0, 32);
            digestSha3.DoFinal(stepOne, 0);

            // step 2) perform ripemd160 on previous step
            var digestRipeMd160 = new RipeMD160Digest();
            var stepTwo         = new byte[20];

            digestRipeMd160.BlockUpdate(stepOne, 0, 32);
            digestRipeMd160.DoFinal(stepTwo, 0);

            // step3) prepend network byte
            var stepThree =
                CryptoBytes.FromHexString(string.Concat(network == 0x68 ? 68 : 98, CryptoBytes.ToHexStringLower(stepTwo)));

            // step 4) perform sha3 on previous step
            var stepFour = new byte[32];

            digestSha3.BlockUpdate(stepThree, 0, 21);
            digestSha3.DoFinal(stepFour, 0);

            // step 5) retrieve checksum
            var stepFive = new byte[4];

            Array.Copy(stepFour, 0, stepFive, 0, 4);

            // step 6) append stepFive to resulst of stepThree
            var stepSix = new byte[25];

            Array.Copy(stepThree, 0, stepSix, 0, 21);
            Array.Copy(stepFive, 0, stepSix, 21, 4);

            // step 7) return base 32 encode address byte array

            return(new Utils.Base32Encoder().Encode(stepSix).ToUpper());
        }
示例#10
0
 public byte[] CalculateKeccakHash(byte[] value)
 {
     var digest = new KeccakDigest(256);
     var output = new byte[digest.GetDigestSize()];
     digest.BlockUpdate(value, 0, value.Length);
     digest.DoFinal(output, 0);
     return output;
 }
示例#11
0
        public void TestKeccak()
        {
            byte[] source = Encoding.ASCII.GetBytes(
                "asdçflkjasçfjaçrlgjaçorigjkljbçladkfjgsaºperouiwa89tuhyjkvsldkfjçaoigfjsadfjkhsdkgjhdlkgjhdkfjbnsdflçkgsriaugfukasyfgskaruyfgsaekufygvsanfbvsdj,fhgwukaygsja,fvkusayfguwayfgsnvfuksaygfkuybhsngfukayeghsmafbsjkfgwlauifgjkshfbilçehrkluayh");

            var keccak128Test = new KeccakDigest(128);
            var keccak224Test = new KeccakDigest(224);
            var keccak256Test = new KeccakDigest(256);
            var keccak288Test = new KeccakDigest(288);
            var keccak384Test = new KeccakDigest(384);
            var keccak512Test = new KeccakDigest(512);

            for (int i = 0; i < 10000; i++)
            {
                //can't find any ground truth for this one, https://8gwifi.org/MessageDigest.jsp is the only one but when comparing to other site's results for other keccaks it doesnt match up with them

                /*var output1 = new byte[keccak128Test.GetDigestSize()];
                 * keccak128Test.BlockUpdate(source, 0, source.Length);
                 * keccak128Test.DoFinal(output1, 0);
                 * var target1 = Base16.Decode("a896124a35603f3766d9d41dade89f9b");*/


                var output2 = new byte[keccak224Test.GetDigestSize()];
                keccak224Test.BlockUpdate(source, 0, source.Length);
                keccak224Test.DoFinal(output2, 0);
                var target2 = Base16.Decode("3c8aa5706aabc26dee19b466e77f8947f801762ca64316fdf3a2434a"); //https://emn178.github.io/online-tools/keccak_224.html

                var output3 = new byte[keccak256Test.GetDigestSize()];
                keccak256Test.BlockUpdate(source, 0, source.Length);
                keccak256Test.DoFinal(output3, 0);
                var target3 = Base16.Decode("09D3FA337D33E1BEB3C3D560D93F5FB57C66BC3E044127816F42494FA4947A92"); //https://asecuritysite.com/encryption/sha3

                //can't find any ground truth for this one, https://8gwifi.org/MessageDigest.jsp is the only one but when comparing to other site's results for other keccaks it doesnt match up with them

                /*var output4 = new byte[keccak288Test.GetDigestSize()];
                 * keccak288Test.BlockUpdate(source, 0, source.Length);
                 * keccak288Test.DoFinal(output4, 0);
                 * var target4 = System.Convert.FromBase64String("");*/

                var output5 = new byte[keccak384Test.GetDigestSize()];
                keccak384Test.BlockUpdate(source, 0, source.Length);
                keccak384Test.DoFinal(output5, 0);
                var target5 = Base16.Decode("B1EA01288A8ECA553687E92943FC8E8D22B3B918462B7708FCB011B8EF28F60E7072FE2623E624DEBD00F8CF46B1F967"); //https://asecuritysite.com/encryption/sha3

                var output6 = new byte[keccak512Test.GetDigestSize()];
                keccak512Test.BlockUpdate(source, 0, source.Length);
                keccak512Test.DoFinal(output6, 0);
                var target6 = Base16.Decode("1057C35F3364A9C7D7EFB5B2AB48D9A71373DCA1E3680CBF6734DA5E896DD7DE2901A678240A1C936598A6C58E6253A9747E2715BBD559AA9A5DA9302B815BAC"); //https://asecuritysite.com/encryption/sha3

                //Assert.IsTrue(output1.SequenceEqual(target1));
                //Assert.IsTrue(output2.SequenceEqual(target2));
                Assert.IsTrue(output3.SequenceEqual(target3));
                //Assert.IsTrue(output4.SequenceEqual(target4));
                Assert.IsTrue(output5.SequenceEqual(target5));
                Assert.IsTrue(output6.SequenceEqual(target6));
            }
        }
示例#12
0
        public static byte[] ToKeccakHash(this byte[] value)
        {
            var digest = new KeccakDigest(256);
            var output = new byte[digest.GetDigestSize()];

            digest.BlockUpdate(value, 0, value.Length);
            digest.DoFinal(output, 0);
            return(output);
        }
示例#13
0
        public static byte[] ComputeSha3KeccakDigest(byte[] data, int bitLength)
        {
            var digest = new KeccakDigest(bitLength);

            byte[] buffer = new byte[digest.GetDigestSize()];
            digest.BlockUpdate(data, 0, data.Length);
            digest.DoFinal(buffer, 0);
            return(buffer);
        }
示例#14
0
    public static byte[] HashKeccak256(byte[] src)
    {
        KeccakDigest sha = new KeccakDigest(256);

        sha.BlockUpdate(src, 0, src.Length);
        byte[] output = new byte[sha.GetDigestSize()];
        sha.DoFinal(output, 0);
        return(output);
    }
示例#15
0
        /// <summary>
        /// Do hash
        /// </summary>
        /// <param name="data">Data</param>
        byte[] CalculateHash(byte[] data)
        {
            KeccakDigest digest = new KeccakDigest(256);

            byte[] raw = new byte[digest.GetDigestSize()];
            digest.BlockUpdate(data, 0, data.Length);
            digest.DoFinal(raw, 0);
            return(raw);
        }
示例#16
0
文件: Hash.cs 项目: lspz/VeChainCore
        public static byte[] Keccac256(byte[] data)
        {
            KeccakDigest k = new KeccakDigest(256);

            k.BlockUpdate(data, 0, data.Length);
            var hash = new byte[32];

            k.DoFinal(hash, 0);
            return(hash);
        }
示例#17
0
        /// <summary>
        /// Keccak256 hashing algorithm
        /// </summary>
        /// <param name="StringIn"></param>
        /// <returns></returns>
        public static string Keccak256HexHashString(string StringIn)
        {
            var sha3 = new KeccakDigest(256);

            byte[] hash  = new byte[sha3.GetDigestSize()];
            byte[] value = Encoding.Default.GetBytes(StringIn);
            sha3.BlockUpdate(value, 0, value.Length);
            sha3.DoFinal(hash, 0);
            return(ToHex(hash, false));
        }
示例#18
0
        public string CalculateHash(string value)
        {
            var digest = new KeccakDigest(256);
            var output = new byte[digest.GetDigestSize()];
            var input  = Encoding.UTF8.GetBytes(value);

            digest.BlockUpdate(input, 0, input.Length);
            digest.DoFinal(output, 0);
            return(output.ToHex());
        }
示例#19
0
        /// <summary>
        /// Hashes the specified payload.
        /// </summary>
        /// <param name="payload">The payload.</param>
        /// <returns>The transaction hash.</returns>
        internal static byte[] Hasher(byte[] payload)
        {
            var hash       = new byte[32];
            var sha3Hasher = new KeccakDigest(256);

            sha3Hasher.BlockUpdate(payload, 0, payload.Length);
            sha3Hasher.DoFinal(hash, 0);

            return(hash);
        }
示例#20
0
文件: Hash.cs 项目: lovecpus/mineral
        public static byte[] SHA3(this byte[] data)
        {
            KeccakDigest digest = new KeccakDigest(256);

            byte[] output = new byte[digest.GetDigestSize()];
            digest.BlockUpdate(data, 0, data.Length);
            digest.DoFinal(output, 0);

            return(output);
        }
示例#21
0
        public static byte[] Hash(byte[] bytes, int bitLength)
        {
            var digest = new KeccakDigest(bitLength);
            var output = new byte[digest.GetDigestSize()];

            digest.BlockUpdate(bytes, 0, bytes.Length);
            digest.DoFinal(output, 0);

            return(output);
        }
示例#22
0
        private static byte[] DeriveAddress(PublicKey key)
        {
            byte[] hashPayload = key.Format(false).Skip(1).ToArray();
            var    digest      = new KeccakDigest(256);
            var    output      = new byte[digest.GetDigestSize()];

            digest.BlockUpdate(hashPayload, 0, hashPayload.Length);
            digest.DoFinal(output, 0);

            return(output.Skip(output.Length - 20).ToArray());
        }
示例#23
0
        public static byte[] Keccak256(byte[] data, int offset, int length)
        {
            byte[] buffer = new byte[32];

            var keccakDigest = new KeccakDigest(256);

            keccakDigest.BlockUpdate(data, offset, length);
            keccakDigest.DoFinal(buffer, 0);

            return(buffer);
        }
示例#24
0
        /// <summary>
        /// Returns message hash
        /// </summary>
        public static byte[] Keccak256(byte[] message, int offset, int size)
        {
            var kecc = new KeccakDigest(256);

            kecc.BlockUpdate(message, offset, size);
            var output = new byte[256];

            kecc.DoFinal(output, 0);

            return(output);
        }
示例#25
0
        protected static byte[] ComputeHash(byte[] bytes, int bits)
        {
            var digest = new KeccakDigest(bits);
            var output = new byte[digest.GetDigestSize()];

            byte[] message = bytes ?? new byte[0];
            digest.BlockUpdate(message, 0, message.Length);
            digest.DoFinal(output, 0);

            return(output);
        }
示例#26
0
        public static byte[] KeccakBytes(this IEnumerable <byte> message)
        {
            var bytes  = message as byte[] ?? message.ToArray();
            var digest = new KeccakDigest(256);

            digest.BlockUpdate(bytes, 0, bytes.Length);
            var output = new byte[32];

            digest.DoFinal(output, 0);
            return(output);
        }
示例#27
0
        public static byte[] Keccak256Helper(byte[] _input)
        {
            KeccakDigest Kec256 = new KeccakDigest(256);

            Kec256.Reset();
            byte[] resultHashedKec256 = new byte[32];
            Kec256.BlockUpdate(_input, 0, _input.Length);
            Kec256.DoFinal(resultHashedKec256, 0);

            return(resultHashedKec256);
        }
示例#28
0
        /// <summary>
        /// Produces a <see cref="PrivateKeyAccountClient"/> from a given <see cref="SecureString"/> of any size.
        /// </summary>
        /// <remarks>
        /// Takes a SecureString, hashes with Sha3 and converts the produced bytes to a 64 char hex string. The <see cref="StringUtils"/> class contains methods to convert to or from <see cref="SecureString"/>.
        /// </remarks>
        /// <param name="data">The data to convert to a private key.</param>
        /// <returns>A <see cref="PrivateKeyAccountClient"/> that can be used to initiate transactions.</returns>
        public PrivateKeyAccountClient FromNewDataPrivateKey(SecureString data)
        {
            var digestSha3 = new KeccakDigest(256);
            var dataBytes  = Encoding.Default.GetBytes(StringUtils.ConvertToUnsecureString(data));
            var pkBytes    = new byte[32];

            digestSha3.BlockUpdate(dataBytes, 0, 32);
            digestSha3.DoFinal(pkBytes, 0);
            var sk = StringUtils.ToSecureString(CryptoBytes.ToHexStringLower(pkBytes));

            return(FromPrivateKey(new PrivateKey(sk)));
        }
示例#29
0
        /// <summary>
        /// Gets the SHA3 digest from the specified data.
        /// </summary>
        /// <param name="data">The data.</param>
        /// <returns>The digest string.</returns>
        public static string GetSha3(MemoryStream data)
        {
            var digest = new KeccakDigest();

            digest.BlockUpdate(data.ToArray(), 0, (int)data.Length);

            var result = new byte[digest.GetDigestSize()];

            digest.DoFinal(result, 0);

            return(BitConverter.ToString(result).Replace("-", ""));
        }
示例#30
0
        /// <summary>
        /// Create an Address from a given public key and network type.
        /// </summary>
        /// <param name="publicKey">The public key.</param>
        /// <param name="networkType">The network type</param>
        /// <returns>Address.</returns>
        public Address(string publicKey, NetworkType.Types networkType)
        {
            // step 1) sha-3(256) public key
            var digestSha3 = new KeccakDigest(256);
            var stepOne    = new byte[Constants.Key];

            digestSha3.BlockUpdate(publicKey.FromHex(), 0, Constants.Key);
            digestSha3.DoFinal(stepOne, 0);

            // step 2) perform ripemd160 on previous step
            var digestRipeMd160 = new RipeMD160Digest();
            var stepTwo         = new byte[Constants.Ripemd160];

            digestRipeMd160.BlockUpdate(stepOne, 0, Constants.Key);
            digestRipeMd160.DoFinal(stepTwo, 0);

            // step3) prepend network byte
            var stepThree = new[] { networkType.GetNetwork() }.Concat(stepTwo).ToArray();

            // step 4) perform sha3 on previous step
            var stepFour = new byte[Constants.Key];

            digestSha3.BlockUpdate(stepThree, 0, Constants.Ripemd160 + 1);
            digestSha3.DoFinal(stepFour, 0);

            // step 5) retrieve checksum
            var stepFive = new byte[Constants.Checksum];

            Array.Copy(stepFour, 0, stepFive, 0, Constants.Checksum);

            // step 6) append stepFive to resulst of stepThree
            var stepSix = new byte[Constants.AddressDecoded];

            Array.Copy(stepThree, 0, stepSix, 0, Constants.Ripemd160 + 1);
            Array.Copy(stepFive, 0, stepSix, Constants.Ripemd160 + 1, Constants.Checksum);

            // step 7) return base 32 encode address byte array
            Initialize(stepSix.ToBase32String());
        }