예제 #1
0
        public int[] Digests(int[] key)
        {
            int security = (int)Math.Floor((double)key.Length / KEY_LENGTH);

            int[] digests     = new int[security * Curl.HashLength];
            int[] keyFragment = new int[KEY_LENGTH];

            ICurl curl = this.GetICurlObject();

            for (int i = 0; i < Math.Floor((double)key.Length / KEY_LENGTH); i++)
            {
                Array.Copy(key, i * KEY_LENGTH, keyFragment, 0, KEY_LENGTH);
                //System.arraycopy(key, i * KEY_LENGTH, keyFragment, 0, KEY_LENGTH);

                for (int j = 0; j < NUMBER_OF_ROUNDS; j++)
                {
                    for (int k = 0; k < 26; k++)
                    {
                        curl.Reset()
                        .Absorb(keyFragment, j * Curl.HashLength, Curl.HashLength)
                        .Squeeze(keyFragment, j * Curl.HashLength, Curl.HashLength);
                    }
                }

                curl.Reset();
                curl.Absorb(keyFragment, 0, keyFragment.Length);
                curl.Squeeze(digests, i * Curl.HashLength, Curl.HashLength);
            }
            return(digests);
        }
예제 #2
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="payload"></param>
        /// <param name="payloadIndex"></param>
        /// <param name="payloadLength"></param>
        /// <param name="key"></param>
        /// <param name="keyIndex"></param>
        /// <param name="keyLength"></param>
        /// <param name="curl"></param>
        public static void UnMask(
            sbyte[] payload, int payloadIndex, int payloadLength,
            sbyte[] key, int keyIndex, int keyLength,
            ICurl curl)
        {
            curl.Absorb(key, keyIndex, keyLength);
            var keyChunk = new sbyte[Constants.HashLength];

            curl.Squeeze(keyChunk);

            for (var i = 0; i < payloadLength; i += Constants.HashLength)
            {
                var left   = payloadLength - i;
                var length = left > Constants.HashLength ? Constants.HashLength : left;

                for (var n = 0; n < length; n++)
                {
                    keyChunk[n] = TritsHelper.Sum(payload[payloadIndex + i + n], (sbyte)-keyChunk[n]);
                }

                Array.Copy(keyChunk, 0, payload, payloadIndex + i, length);
                curl.Absorb(keyChunk, 0, length);

                Array.Copy(curl.Rate, keyChunk, length);
            }
        }
예제 #3
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="seed"></param>
        /// <param name="index"></param>
        /// <param name="curl"></param>
        /// <returns></returns>
        public static sbyte[] Subseed(sbyte[] seed, int index, ICurl curl)
        {
            sbyte[] subseed    = new sbyte[Constants.HashLength];
            int     copyLength = Math.Min(seed.Length, subseed.Length);

            Array.Copy(seed, subseed, copyLength);

            for (var i = 0; i < index; i++)
            {
                for (var j = 0; j < Constants.HashLength; j++)
                {
                    if (++subseed[j] > 1)
                    {
                        subseed[j] = -1;
                    }
                    else
                    {
                        break;
                    }
                }
            }

            curl.Absorb(subseed);  // curl.absorb(&out[0..seed.len()]);
            curl.Squeeze(subseed); // curl.squeeze(&mut out[0..HASH_LENGTH]);
            curl.Reset();

            return(subseed);
        }
예제 #4
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="bundle"></param>
        /// <param name="keySignature"></param>
        /// <param name="index"></param>
        /// <param name="length"></param>
        /// <param name="curl"></param>
        // Takes an input `signature`, and writes its digest out to the first 243 trits
        public static void DigestBundleSignature(sbyte[] bundle, sbyte[] keySignature, int index, int length,
                                                 ICurl curl)
        {
            if (bundle.Length != Constants.HashLength)
            {
                throw new ArgumentException("bundle are not equal HashLength!");
            }

            int totalLength = Constants.KeyLength * CheckSumSecurity(bundle);

            if (totalLength != length)
            {
                throw new ArgumentException("Key space size must be equal to security space size");
            }

            for (int i = 0; i < length / Constants.HashLength; i++)
            {
                int maxCount =
                    (bundle[i * Constants.TryteWidth] +
                     bundle[i * Constants.TryteWidth + 1] * 3 +
                     bundle[i * Constants.TryteWidth + 2] * 9) - Constants.MinTryteValue;

                for (int n = 0; n < maxCount; n++)
                {
                    curl.Reset();
                    curl.Absorb(keySignature, index + i * Constants.HashLength, Constants.HashLength);
                    Array.Copy(curl.State, 0, keySignature, index + i * Constants.HashLength, Constants.HashLength);
                }
            }

            curl.Reset();

            curl.Absorb(keySignature, index, length);
        }
예제 #5
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="subseed"></param>
        /// <param name="security"></param>
        /// <param name="c1"></param>
        /// <param name="c2"></param>
        /// <param name="c3"></param>
        /// <returns></returns>
        public static sbyte[] SubseedToDigest(
            sbyte[] subseed, int security,
            ICurl c1, ICurl c2, ICurl c3)
        {
            sbyte[] digest = new sbyte[Constants.HashLength];

            int length = security * Constants.KeyLength / Constants.HashLength;

            c1.Absorb(subseed);

            for (int i = 0; i < length; i++)
            {
                c1.Squeeze(digest);

                for (int n = 0; n < 27; n++)
                {
                    c2.Reset();
                    c2.Absorb(digest);
                    Array.Copy(c2.State, digest, Constants.HashLength);
                }

                c3.Absorb(digest);
            }

            c3.Squeeze(digest);

            return(digest);
        }
예제 #6
0
        public int[] Digest(int[] normalizedBundleFragment, int[] signatureFragment)
        {
            this.curl.Reset();
            ICurl curl = this.GetICurlObject();

            int[] buffer = new int[Curl.HashLength];

            for (int i = 0; i < NUMBER_OF_ROUNDS; i++)
            {
                Array.Copy(signatureFragment, i * Curl.HashLength, buffer, 0, Curl.HashLength);

                // buffer = Array.Copy(signatureFragment, i * Curl.HashLength, buffer, (i + 1) * Curl.HashLength, (i + 1) * NUMBER_OF_ROUNDS);

                for (int j = normalizedBundleFragment[i] + 13; j-- > 0;)
                {
                    curl.Reset();
                    curl.Absorb(buffer);
                    curl.Squeeze(buffer);
                }
                this.curl.Absorb(buffer);
            }
            this.curl.Squeeze(buffer);

            return(buffer);
        }
예제 #7
0
        // root
        public static int Root(sbyte[] address, sbyte[] hashes, int index, ICurl curl)
        {
            int i            = 1;
            int numBeforeEnd = 0;

            sbyte[] outTrits = new sbyte[Constants.HashLength];
            Array.Copy(address, outTrits, Constants.HashLength);

            for (int n = 0; n < hashes.Length / Constants.HashLength; n++)
            {
                curl.Reset();
                if ((i & index) == 0)
                {
                    numBeforeEnd += 1;

                    curl.Absorb(outTrits);
                    curl.Absorb(hashes, n * Constants.HashLength, Constants.HashLength);
                }
                else
                {
                    curl.Absorb(hashes, n * Constants.HashLength, Constants.HashLength);
                    curl.Absorb(outTrits);
                }

                i <<= 1;

                Array.Copy(curl.Rate, outTrits, Constants.HashLength);
            }

            return(numBeforeEnd);
        }
예제 #8
0
        /// <summary>
        /// Finalizes the bundle using the specified curl implementation
        /// </summary>
        /// <param name="customCurl">The custom curl.</param>
        public void FinalizeBundle(ICurl customCurl)
        {
            customCurl.Reset();

            for (int i = 0; i < Transactions.Count; i++)
            {
                int[] valueTrits = Converter.ToTrits(Transactions[i].Value, 81);

                int[] timestampTrits = Converter.ToTrits(Transactions[i].Timestamp, 27);

                int[] currentIndexTrits = Converter.ToTrits(Transactions[i].CurrentIndex = ("" + i), 27);

                int[] lastIndexTrits = Converter.ToTrits(
                    Transactions[i].LastIndex = ("" + (this.Transactions.Count - 1)), 27);

                string stringToConvert = Transactions[i].Address
                                         + Converter.ToTrytes(valueTrits)
                                         + Transactions[i].Tag +
                                         Converter.ToTrytes(timestampTrits)
                                         + Converter.ToTrytes(currentIndexTrits) +
                                         Converter.ToTrytes(lastIndexTrits);

                int[] t = Converter.ToTrits(stringToConvert);
                customCurl.Absorb(t, 0, t.Length);
            }

            int[] hash = new int[243];
            customCurl.Squeeze(hash, 0, hash.Length);
            string hashInTrytes = Converter.ToTrytes(hash);

            for (int i = 0; i < Transactions.Count; i++)
            {
                Transactions[i].Bundle = hashInTrytes;
            }
        }
예제 #9
0
        /// <summary>
        ///     Finalizes the bundle using the specified curl implementation
        /// </summary>
        /// <param name="customCurl">The custom curl.</param>
        public void FinalizeBundle(ICurl customCurl)
        {
            string hashInTrytes = string.Empty;

            bool validBundle = false;

            while (!validBundle)
            {
                customCurl.Reset();

                for (var i = 0; i < Transactions.Count; i++)
                {
                    var valueTrits = Converter.ToTrits(Transactions[i].Value, 81);

                    var timestampTrits = Converter.ToTrits(Transactions[i].Timestamp, 27);

                    var currentIndexTrits = Converter.ToTrits(Transactions[i].CurrentIndex = i, 27);

                    var lastIndexTrits = Converter.ToTrits(
                        Transactions[i].LastIndex = Transactions.Count - 1, 27);

                    var stringToConvert = Transactions[i].Address
                                          + Converter.ToTrytes(valueTrits)
                                          + Transactions[i].ObsoleteTag +
                                          Converter.ToTrytes(timestampTrits)
                                          + Converter.ToTrytes(currentIndexTrits) +
                                          Converter.ToTrytes(lastIndexTrits);

                    var t = Converter.ToTrits(stringToConvert);
                    customCurl.Absorb(t, 0, t.Length);
                }

                var hash = new sbyte[Sponge.HASH_LENGTH];
                customCurl.Squeeze(hash, 0, hash.Length);
                hashInTrytes = Converter.ToTrytes(hash);

                bool foundValue     = false;
                var  normalizedHash = NormalizedBundle(hashInTrytes);
                foreach (var normalizedHashValue in normalizedHash)
                {
                    if (normalizedHashValue == 13 /* = M */)
                    {
                        foundValue = true;
                        // Insecure bundle. Increment Tag and recompute bundle hash.
                        var obsoleteTagTrits = Converter.ToTrits(Transactions[0].ObsoleteTag);
                        Converter.Increment(obsoleteTagTrits, 81);
                        Transactions[0].ObsoleteTag = Converter.ToTrytes(obsoleteTagTrits);
                        break;
                    }
                }

                validBundle = !foundValue;
            }

            foreach (var transaction in Transactions)
            {
                transaction.Bundle = hashInTrytes;
            }
        }
예제 #10
0
 /// <summary>
 /// Creates an api object that uses the specified connection settings to connect to a node
 /// </summary>
 /// <param name="host">hostname or API address of a node to interact with</param>
 /// <param name="port">tcp/udp port</param>
 /// <param name="curl">a custom curl implementation to be used to perform the pow. Use the other constructor in order to use the default curl implementation provided by the library </param>
 public IotaApi(string host, int port, ICurl curl) : base(host, port)
 {
     if (curl == null)
     {
         throw new ArgumentNullException(nameof(curl));
     }
     this.curl = curl;
 }
예제 #11
0
        private static MerkleNode CreateMerkleLeaf(
            sbyte[] seed, int index,
            int security,
            ICurl c1, ICurl c2, ICurl c3)
        {
            sbyte[] hash = ComputeHash(seed, index, security, c1, c2, c3);

            return(new MerkleNode(null, hash, null));
        }
예제 #12
0
        public bool Search(
            int security, int offset, int length,
            ICurl tcurl)
        {
            //
            SearchPrepareTrits(tcurl.State, offset);

            //
            return(SearchCpu(tcurl.State, offset, length, security));
        }
예제 #13
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="digest"></param>
        /// <param name="curl"></param>
        /// <returns></returns>
        public static sbyte[] Address(sbyte[] digest, ICurl curl)
        {
            sbyte[] address = new sbyte[Constants.AddressLength];

            curl.Absorb(digest);
            curl.Squeeze(address);
            curl.Reset();

            return(address);
        }
예제 #14
0
        private static string CalculateChecksum(string address)
        {
            ICurl curl = SpongeFactory.Create(SpongeFactory.Mode.KERL);

            curl.Reset();
            curl.Absorb(Converter.ToTrits(address));
            sbyte[] checksumTrits = new sbyte[Sponge.HASH_LENGTH];
            curl.Squeeze(checksumTrits);
            string checksum = Converter.ToTrytes(checksumTrits);

            return(checksum.Substring(72, 9));
        }
예제 #15
0
 /// <summary>
 /// </summary>
 /// <param name="curl"></param>
 public Signing(ICurl curl)
 {
     // ReSharper disable once ConvertIfStatementToNullCoalescingExpression
     if (curl == null)
     {
         _curl = new Kerl();
     }
     else
     {
         _curl = curl;
     }
 }
예제 #16
0
        /**
         * @param inSeed
         * @param index
         * @param security
         * @return
         * @throws ArgumentException is thrown when the specified security level is not valid.
         */
        public int[] Key(int[] inSeed, int index, int security)
        {
            if (security < 1)
            {
                throw new ArgumentException(Constants.INVALID_SECURITY_LEVEL_INPUT_ERROR);
            }

            int[] seed = (int[])inSeed.Clone();

            // Derive subseed.
            for (int i = 0; i < index; i++)
            {
                for (int j = 0; j < seed.Length; j++)
                {
                    if (++seed[j] > 1)
                    {
                        seed[j] = -1;
                    }
                    else
                    {
                        break;
                    }
                }
            }

            ICurl curl = this.GetICurlObject();

            curl.Reset();
            curl.Absorb(seed, 0, seed.Length);
            // seed[0..HASH_LENGTH] contains subseed
            curl.Squeeze(seed, 0, seed.Length);
            curl.Reset();
            // absorb subseed
            curl.Absorb(seed, 0, seed.Length);

            int[] key    = new int[security * Curl.HashLength * NUMBER_OF_ROUNDS]; //TODO is this not 81!!
            int[] buffer = new int[seed.Length];
            int   offset = 0;

            while (security-- > 0)
            {
                for (int i = 0; i < NUMBER_OF_ROUNDS; i++)
                {
                    curl.Squeeze(buffer, 0, seed.Length);

                    Array.Copy(buffer, 0, key, offset, Curl.HashLength);

                    offset += Curl.HashLength;
                }
            }
            return(key);
        }
예제 #17
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="trunkTransaction"></param>
        /// <param name="branchTransaction"></param>
        /// <param name="minWeightMagnitude"></param>
        /// <param name="trytes"></param>
        /// <returns></returns>
        public AttachToTangleResponse AttachToTangle(
            string trunkTransaction, string branchTransaction,
            int minWeightMagnitude, string[] trytes)
        {
            var response = new AttachToTangleResponse
            {
                Trytes = new List <string>()
            };

            string previousTransaction = null;

            foreach (var t in trytes)
            {
                var txn = new Transaction(t)
                {
                    TrunkTransaction  = previousTransaction ?? trunkTransaction,
                    BranchTransaction = previousTransaction == null ? branchTransaction : trunkTransaction
                };

                if (string.IsNullOrEmpty(txn.Tag) || Regex.IsMatch(txn.Tag, "9*"))
                {
                    txn.Tag = txn.ObsoleteTag;
                }

                txn.AttachmentTimestamp           = TimeStamp.Now();
                txn.AttachmentTimestampLowerBound = 0;
                txn.AttachmentTimestampUpperBound = 3_812_798_742_493L;

                // POW
                var transactionTrits = Converter.ToTrits(txn.ToTrytes());
                if (!_pearlDiver.Search(transactionTrits, minWeightMagnitude, 0))
                {
                    throw new IllegalStateException("PearlDiver search failed");
                }

                // Hash
                var hash = new sbyte[Sponge.HASH_LENGTH];

                ICurl curl = SpongeFactory.Create(SpongeFactory.Mode.CURLP81);
                curl.Reset();
                curl.Absorb(transactionTrits);
                curl.Squeeze(hash);

                previousTransaction = Converter.ToTrytes(hash);

                response.Trytes.Add(Converter.ToTrytes(transactionTrits));
            }

            response.Trytes.Reverse();
            return(response);
        }
예제 #18
0
        public void TestLongSeedKeyGeneration()
        {
            ICurl   curl    = SpongeFactory.Create(SpongeFactory.Mode.KERL);
            Signing signing = new Signing(curl);
            string  seed    = "EV9QRJFJZVFNLYUFXWKXMCRRPNAZYQVEYB9VEPUHQNXJCWKZFVUCTQJFCUAMXAHMMIUQUJDG9UGGQBPIY";

            for (int i = Constants.MIN_SECURITY_LEVEL; i < Constants.MAX_SECURITY_LEVEL; i++)
            {
                sbyte[] key1 = signing.Key(Converter.ToTrits(seed), 0, i);
                Assert.AreEqual(Constants.KEY_LENGTH * i, key1.Length);
                sbyte[] key2 = signing.Key(Converter.ToTrits(seed + seed), 0, i);
                Assert.AreEqual(Constants.KEY_LENGTH * i, key2.Length);
                sbyte[] key3 = signing.Key(Converter.ToTrits(seed + seed + seed), 0, i);
                Assert.AreEqual(Constants.KEY_LENGTH * i, key3.Length);
            }
        }
예제 #19
0
        /// <summary>
        ///  Generates a new address
        /// </summary>
        /// <param name="seed"></param>
        /// <param name="index"></param>
        /// <param name="checksum"></param>
        /// <param name="curl"></param>
        /// <returns></returns>
        internal static string NewAddress(string seed, int index, bool checksum, ICurl curl)
        {
            Signing   signing   = new Signing(curl);
            Stopwatch stopWatch = new Stopwatch();

            stopWatch.Start();
            // Get the elapsed time as a TimeSpan value.
            TimeSpan ts = stopWatch.Elapsed;

            // Format and display the TimeSpan value.
            string elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}",
                                               ts.Hours, ts.Minutes, ts.Seconds,
                                               ts.Milliseconds / 10);

            Console.WriteLine(elapsedTime);

            int[] key = signing.Key(Converter.ToTrits(seed), index, 2);

            ts          = stopWatch.Elapsed;
            elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}",
                                        ts.Hours, ts.Minutes, ts.Seconds,
                                        ts.Milliseconds / 10);
            Console.WriteLine(elapsedTime);

            int[] digests = signing.Digests(key);

            ts          = stopWatch.Elapsed;
            elapsedTime = String.Format("After Digest {0:00}:{1:00}:{2:00}.{3:00}",
                                        ts.Hours, ts.Minutes, ts.Seconds,
                                        ts.Milliseconds / 10);
            Console.WriteLine(elapsedTime);

            int[] addressTrits = signing.Address(digests);
            ts          = stopWatch.Elapsed;
            elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}",
                                        ts.Hours, ts.Minutes, ts.Seconds,
                                        ts.Milliseconds / 10);
            Console.WriteLine(elapsedTime);
            string address = Converter.ToTrytes(addressTrits);

            if (checksum)
            {
                address = Checksum.AddChecksum(address);
            }

            return(address);
        }
예제 #20
0
        public void UpdateFromTrytes(string trytes, ICurl curl)
        {
            if (string.IsNullOrEmpty(trytes))
            {
                throw new ArgumentNullException(nameof(trytes));
            }

            if (curl == null)
            {
                throw new ArgumentNullException(nameof(curl));
            }

            // validity check
            for (int i = 2279; i < 2295; i++)
            {
                if (trytes[i] != '9')
                {
                    throw new ArgumentException("position " + i + "must not be '9'");
                }
            }

            var transactionTrits = Crypto.Converter.GetTrits(trytes);

            sbyte[] hash = new sbyte[243];

            // generate the correct transaction hash
            curl.Reset()
            .Absorb(transactionTrits, 0, transactionTrits.Length)
            .Squeeze(hash, 0, hash.Length);

            Hash = Crypto.Converter.GetTrytes(hash);
            SignatureFragment = trytes.Substring(0, 2187);
            Address           = trytes.Substring(2187, 2268 - 2187);
            Value             = "" + Crypto.Converter.GetInt(ArrayUtils.SubArray(transactionTrits, 6804, 6837));
            Tag               = trytes.Substring(2295, 2322 - 2295);
            Timestamp         = "" + Crypto.Converter.GetInt(ArrayUtils.SubArray(transactionTrits, 6966, 6993));
            CurrentIndex      = "" + Crypto.Converter.GetInt(ArrayUtils.SubArray(transactionTrits, 6993, 7020));
            LastIndex         = "" + Crypto.Converter.GetInt(ArrayUtils.SubArray(transactionTrits, 7020, 7047));
            Bundle            = trytes.Substring(2349, 2430 - 2349);
            TrunkTransaction  = trytes.Substring(2430, 2511 - 2430);
            BranchTransaction = trytes.Substring(2511, 2592 - 2511);
            Nonce             = trytes.Substring(2592, 2673 - 2592);
        }
예제 #21
0
        public void UpdateFromTrytes(string trytes, ICurl curl)
        {
            if (string.IsNullOrEmpty(trytes))
            {
                throw new ArgumentNullException(nameof(trytes));
            }

            if (curl == null)
            {
                throw new ArgumentNullException(nameof(curl));
            }

            this.curl = curl;

            // validity check
            for (int i = 2279; i < 2295; i++)
            {
                if (trytes[i] != '9')
                {
                    throw new ArgumentException("position " + i + "must not be '9'");
                }
            }

            this.RawTrytes = trytes;

            SignatureFragment = trytes.Substring(0, 2187);
            Address           = trytes.Substring(2187, 2268 - 2187);
            Value             = Converter.ToLongValue(trytes, 2268, 2295);
            ObsoleteTag       = trytes.Substring(2295, 2322 - 2295);
            Timestamp         = Converter.ToLongValue(trytes, 2322, 2331);
            CurrentIndex      = (int)Converter.ToLongValue(trytes, 2331, 2340);
            LastIndex         = (int)Converter.ToLongValue(trytes, 2340, 2349);
            Bundle            = trytes.Substring(2349, 2430 - 2349);
            TrunkTransaction  = trytes.Substring(2430, 2511 - 2430);
            BranchTransaction = trytes.Substring(2511, 2592 - 2511);
            Tag = trytes.Substring(2592, 2619 - 2592);
            AttachmentTimestamp           = Converter.ToLongValue(trytes, 2619, 2628);
            AttachmentTimestampLowerBound = Converter.ToLongValue(trytes, 2628, 2637);
            AttachmentTimestampUpperBound = Converter.ToLongValue(trytes, 2637, 2646);
            Nonce = trytes.Substring(2646, 2673 - 2646);
        }
예제 #22
0
        /// <summary>
        ///     Initializes a new instance of the <see cref="Transaction" /> class.
        /// </summary>
        /// <param name="trytes">The trytes representing the transaction</param>
        /// <param name="curl">The curl implementation.</param>
        /// <exception cref="System.ArgumentException">
        ///     trytes must non-null
        ///     or
        ///     position " + i + "must not be '9'
        /// </exception>
        public Transaction(string trytes, ICurl curl)
        {
            if (string.IsNullOrEmpty(trytes))
            {
                throw new ArgumentException("trytes must non-null");
            }

            // validity check
            for (var i = 2279; i < 2295; i++)
            {
                if (trytes[i] != '9')
                {
                    throw new ArgumentException("position " + i + "must not be '9'");
                }
            }

            var transactionTrits = Converter.ToTrits(trytes);
            var hash             = new int[243];

            // generate the correct transaction hash
            curl.Reset();
            curl.Absorb(transactionTrits, 0, transactionTrits.Length);
            curl.Squeeze(hash, 0, hash.Length);

            Hash = Converter.ToTrytes(hash);
            SignatureMessageFragment = trytes.Substring(0, 2187);
            Address           = trytes.Substring(2187, 2268 - 2187);
            Value             = Converter.ToLongValue(ArrayUtils.SubArray(transactionTrits, 6804, 6837));
            ObsoleteTag       = trytes.Substring(2295, 2322 - 2295);
            Timestamp         = Converter.ToLongValue(ArrayUtils.SubArray(transactionTrits, 6966, 6993));
            CurrentIndex      = Converter.ToLongValue(ArrayUtils.SubArray(transactionTrits, 6993, 7020));
            LastIndex         = Converter.ToLongValue(ArrayUtils.SubArray(transactionTrits, 7020, 7047));
            Bundle            = trytes.Substring(2349, 2430 - 2349);
            TrunkTransaction  = trytes.Substring(2430, 2511 - 2430);
            BranchTransaction = trytes.Substring(2511, 2592 - 2511);
            Tag = trytes.Substring(2592, 2619 - 2592);
            AttachmentTimestamp           = Converter.ToLongValue(ArrayUtils.SubArray(transactionTrits, 7857, 7884));
            AttachmentTimestampLowerBound = Converter.ToLongValue(ArrayUtils.SubArray(transactionTrits, 7884, 7911));
            AttachmentTimestampUpperBound = Converter.ToLongValue(ArrayUtils.SubArray(transactionTrits, 7911, 7938));
            Nonce = trytes.Substring(2646, 2673 - 2646);
        }
예제 #23
0
        public static MerkleNode CreateMerkleTree(
            sbyte[] seed, int index, uint count,
            int security,
            ICurl c1,
            ICurl c2,
            ICurl c3)
        {
            if (count == 0)
            {
                return(null);
            }

            if (count == 1)
            {
                return(CreateMerkleLeaf(seed, index, security, c1, c2, c3));
            }

            uint ct = NextPowerOfTwo(count);

            return(CreateMerkleNode(seed, index, count, ct, security, c1, c2, c3));
        }
예제 #24
0
        /// <summary>
        ///  Generates a new address
        /// </summary>
        /// <param name="seed"></param>
        /// <param name="index"></param>
        /// <param name="checksum"></param>
        /// <param name="curl"></param>
        /// <returns></returns>
        public static string NewAddress(int[] privateKey, bool checksum, ICurl curl, CancellationToken cancellationToken)
        {
            Signing   signing   = new Signing(curl);
            Stopwatch stopWatch = new Stopwatch();

            stopWatch.Start();
            // Get the elapsed time as a TimeSpan value.
            TimeSpan ts = stopWatch.Elapsed;

            ts = stopWatch.Elapsed;
            var elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}",
                                            ts.Hours, ts.Minutes, ts.Seconds,
                                            ts.Milliseconds / 10);

            cancellationToken.ThrowIfCancellationRequested();

            int[] digests = signing.Digests(privateKey);

            ts          = stopWatch.Elapsed;
            elapsedTime = String.Format("After Digest {0:00}:{1:00}:{2:00}.{3:00}",
                                        ts.Hours, ts.Minutes, ts.Seconds,
                                        ts.Milliseconds / 10);
            cancellationToken.ThrowIfCancellationRequested();

            int[] addressTrits = signing.Address(digests);
            ts          = stopWatch.Elapsed;
            elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}",
                                        ts.Hours, ts.Minutes, ts.Seconds,
                                        ts.Milliseconds / 10);
            cancellationToken.ThrowIfCancellationRequested();

            string address = Converter.ToTrytes(addressTrits);

            if (checksum)
            {
                address = Checksum.AddChecksum(address);
            }

            return(address);
        }
예제 #25
0
        private static MerkleNode Combine(
            sbyte[] seed, int index,
            uint count, uint remainingWidth,
            int security,
            ICurl c1, ICurl c2, ICurl c3)
        {
            uint rightCount = NextPowerOfTwo(count) >> 1;
            uint leftCount  = count - rightCount;

            var left  = CreateMerkleNode(seed, index, leftCount, remainingWidth >> 1, security, c1, c2, c3);
            var right = CreateMerkleNode(seed, (int)(index + leftCount), rightCount, remainingWidth >> 1, security, c1,
                                         c2,
                                         c3);

            if (left != null && (left.IsLeaf || left.IsFullNode))
            {
                c1.Absorb(left.Hash);
            }
            else
            {
                c1.Absorb(NullHash);
            }

            if (right != null && (right.IsLeaf || right.IsFullNode))
            {
                c1.Absorb(right.Hash);
            }
            else
            {
                c1.Absorb(NullHash);
            }

            sbyte[] hash = new sbyte[Constants.HashLength];
            c1.Squeeze(hash, 0, hash.Length);
            c1.Reset();

            return(new MerkleNode(left, hash, right));
        }
예제 #26
0
        public int[] Digest(int[] normalizedBundleFragment, int[] signatureFragment)
        {
            curl.Reset();
            int[] buffer = new int[243];

            for (int i = 0; i < 27; i++)
            {
                buffer = ArrayUtils.SubArray(signatureFragment, i * 243, 243);
                ;
                ICurl jCurl = curl.Clone();

                for (int j = normalizedBundleFragment[i] + 13; j-- > 0;)
                {
                    jCurl.Reset();
                    jCurl.Absorb(buffer);
                    jCurl.Squeeze(buffer);
                }
                curl.Absorb(buffer);
            }
            curl.Squeeze(buffer);

            return(buffer);
        }
예제 #27
0
        private static MerkleNode CreateMerkleNode(
            sbyte[] seed, int index,
            uint remainingCount, uint remainingWidth,
            int security,
            ICurl c1, ICurl c2, ICurl c3)
        {
            if (remainingCount == 0)
            {
                return(null);
            }

            if (remainingWidth == 0)
            {
                return(null);
            }

            if (remainingWidth == 1)
            {
                return(CreateMerkleLeaf(seed, index, security, c1, c2, c3));
            }

            return(Combine(seed, index, remainingCount, remainingWidth, security, c1, c2, c3));
        }
예제 #28
0
        private static sbyte[] ComputeHash(
            sbyte[] seed, int index,
            int security,
            ICurl c1, ICurl c2, ICurl c3)
        {
            sbyte[] subseed = HashHelper.Subseed(seed, index, c1);

            c1.Reset();

            //iss::subseed_to_digest(&subseed, security, &mut hash, c1, c2, c3);
            sbyte[] digest = HashHelper.SubseedToDigest(subseed, security, c1, c2, c3);

            c1.Reset();
            c2.Reset();
            c3.Reset();

            //iss::address(&mut hash, c1);
            sbyte[] address = HashHelper.Address(digest, c1);

            c1.Reset();

            return(address);
        }
예제 #29
0
        /// <summary>
        ///     Finalizes the bundle using the specified curl implementation
        /// </summary>
        /// <param name="customCurl">The custom curl.</param>
        public void FinalizeBundle(ICurl customCurl)
        {
            customCurl.Reset();

            for (var i = 0; i < Transactions.Count; i++)
            {
                var valueTrits = Converter.ToTrits(Transactions[i].Value, 81);

                var timestampTrits = Converter.ToTrits(Transactions[i].Timestamp, 27);

                var currentIndexTrits = Converter.ToTrits(Transactions[i].CurrentIndex = i, 27);

                var lastIndexTrits = Converter.ToTrits(
                    Transactions[i].LastIndex = Transactions.Count - 1, 27);

                var stringToConvert = Transactions[i].Address
                                      + Converter.ToTrytes(valueTrits)
                                      + Transactions[i].Tag +
                                      Converter.ToTrytes(timestampTrits)
                                      + Converter.ToTrytes(currentIndexTrits) +
                                      Converter.ToTrytes(lastIndexTrits);

                var t = Converter.ToTrits(stringToConvert);
                customCurl.Absorb(t, 0, t.Length);
            }

            var hash = new int[243];

            customCurl.Squeeze(hash, 0, hash.Length);
            var hashInTrytes = Converter.ToTrytes(hash);

            foreach (var transaction in Transactions)
            {
                transaction.Bundle = hashInTrytes;
            }
        }
예제 #30
0
 /// <summary>
 ///     Creates an api object that uses the specified connection settings to connect to a node
 /// </summary>
 /// <param name="host">hostname or API address of a node to interact with</param>
 /// <param name="port">tcp/udp port</param>
 /// <param name="curl">
 ///     a custom curl implementation to be used to perform the pow. Use the other constructor in order to
 ///     use the default curl implementation provided by the library
 /// </param>
 public IotaApi(string host, int port, ICurl curl) : base(host, port)
 {
     _curl = curl ?? throw new ArgumentNullException(nameof(curl));
 }