Exemplo n.º 1
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);
        }
Exemplo n.º 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);
            }
        }
Exemplo n.º 3
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);
        }
Exemplo n.º 4
0
        /// <summary>
        /// </summary>
        /// <param name="digests">digest trytes</param>
        public void AddAddressDigest(string[] digests)
        {
            foreach (var digest in digests)
            {
                // Get trits of digest
                var digestTrits = Converter.ToTrits(digest);

                // Absorb digest
                _curl.Absorb(digestTrits, 0, digestTrits.Length);
            }
        }
Exemplo n.º 5
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);
        }
Exemplo n.º 6
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);
        }
Exemplo n.º 7
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);
        }
Exemplo n.º 8
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);
        }
Exemplo n.º 9
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);
        }
Exemplo n.º 10
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;
            }
        }
Exemplo n.º 11
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;
            }
        }
Exemplo n.º 12
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);
        }
Exemplo n.º 13
0
        public int[] Key(int[] seed, int index, int length)
        {
            int[] subseed = seed;

            for (int i = 0; i < index; i++)
            {
                for (int j = 0; j < 243; j++)
                {
                    if (++subseed[j] > 1)
                    {
                        subseed[j] = -1;
                    }
                    else
                    {
                        break;
                    }
                }
            }

            curl.Reset();
            curl.Absorb(subseed, 0, subseed.Length);
            curl.Squeeze(subseed, 0, subseed.Length);
            curl.Reset();
            curl.Absorb(subseed, 0, subseed.Length);

            IList <int> key = new List <int>();

            int[] buffer = new int[subseed.Length];
            int   offset = 0;

            while (length-- > 0)
            {
                for (int i = 0; i < 27; i++)
                {
                    curl.Squeeze(buffer, offset, buffer.Length);
                    for (int j = 0; j < 243; j++)
                    {
                        key.Add(buffer[j]);
                    }
                }
            }
            return(ToIntArray(key));
        }
Exemplo n.º 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));
        }
Exemplo n.º 15
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);
        }
Exemplo n.º 16
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));
        }
Exemplo n.º 17
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="keySpace"></param>
        /// <param name="index"></param>
        /// <param name="length"></param>
        /// <param name="security"></param>
        /// <param name="curl"></param>
        // Take first 243 trits of key_space as subseed, and write key out to key_space
        public static void Key(sbyte[] keySpace, int index, int length, int security, ICurl curl)
        {
            int totalLength = security * Constants.KeyLength;

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

            curl.Absorb(keySpace, index, Constants.HashLength);
            curl.Squeeze(keySpace, index, length);

            for (int divOffset = 0; divOffset < length / Constants.HashLength; divOffset++)
            {
                int offset = divOffset * Constants.HashLength;
                curl.Reset();
                curl.Absorb(keySpace, index + offset, Constants.HashLength);

                Array.Copy(curl.State, 0, keySpace, index + offset, Constants.HashLength);
            }

            curl.Reset();
        }
Exemplo n.º 18
0
        public static string FinalizeBundleHash(this IEnumerable <TransactionItem> transactionItems, ICurl customCurl)
        {
            customCurl.Reset();
            var    transactionCount = transactionItems.Count();
            bool   valid            = false;
            string hashInTrytes     = "";

            while (!valid)
            {
                for (int i = 0; i < transactionCount; i++)
                {
                    var transaction = transactionItems.ElementAt(i);
                    transaction.CurrentIndex = i;
                    transaction.LastIndex    = transactionCount - 1;

                    var trytes = transaction.GetBundleTrytes();

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

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

                bool found = false;
                var  normalizedBundleValues = NormalizedBundle(hashInTrytes);
                foreach (int normalizedBundleValue in normalizedBundleValues)
                {
                    if (normalizedBundleValue == 13)
                    {
                        found = true;
                        var obsoleteTagTrits = Converter.ToTritsString(transactionItems.First().ObsoleteTag);
                        Converter.Increment(obsoleteTagTrits, 81);
                        transactionItems.First().ObsoleteTag = Converter.ToTrytes(obsoleteTagTrits);
                        customCurl.Reset();
                    }
                }
                valid = !found;
            }

            foreach (var transaction in transactionItems)
            {
                transaction.Bundle = hashInTrytes;
            }

            return(hashInTrytes);
        }
Exemplo n.º 19
0
        /// <summary>
        /// </summary>
        /// <param name="seed"></param>
        /// <param name="index"></param>
        /// <param name="security"></param>
        /// <returns></returns>
        public int[] Key(int[] seed, int index, int security)
        {
            var subseed = new int[seed.Length];

            seed.CopyTo(subseed, 0);

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

            _curl.Reset();
            _curl.Absorb(subseed, 0, subseed.Length);
            _curl.Squeeze(subseed, 0, subseed.Length);
            _curl.Reset();
            _curl.Absorb(subseed, 0, subseed.Length);

            var key    = new List <int>();
            var buffer = new int[subseed.Length];
            var offset = 0;

            while (security-- > 0)
            {
                for (var i = 0; i < 27; i++)
                {
                    _curl.Squeeze(buffer, offset, buffer.Length);
                    for (var j = 0; j < 243; j++)
                    {
                        key.Add(buffer[j]);
                    }
                }
            }

            return(key.ToArray());
        }
Exemplo n.º 20
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="payload"></param>
        /// <param name="payloadIndex"></param>
        /// <param name="payloadLength"></param>
        /// <param name="curl"></param>
        public static void UnMaskSlice(sbyte[] payload, int payloadIndex, int payloadLength, ICurl curl)
        {
            var keyChunk = new int[Constants.HashLength];

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

                Array.Copy(curl.Rate, keyChunk, length);

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

                curl.Absorb(payload, payloadIndex + i, length);
            }
        }
Exemplo n.º 21
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);
        }
Exemplo n.º 22
0
        public static string FinalizeBundleHash(this IEnumerable <TransactionItem> transactionItems, ICurl customCurl)
        {
            customCurl.Reset();
            var transactionCount = transactionItems.Count();

            for (int i = 0; i < transactionCount; i++)
            {
                var transaction = transactionItems.ElementAt(i);

                int[] valueTrits = Converter.ToTrits(transaction.Value, 81);

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

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

                int[] lastIndexTrits = Converter.ToTrits(
                    transaction.LastIndex = ("" + (transactionCount - 1)), 27);

                string stringToConvert = transaction.Address
                                         + Converter.ToTrytes(valueTrits)
                                         + transaction.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);

            foreach (var transaction in transactionItems)
            {
                transaction.Bundle = hashInTrytes;
            }

            return(hashInTrytes);
        }
Exemplo n.º 23
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);
        }
Exemplo n.º 24
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;
            }
        }
Exemplo n.º 25
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="bundle"></param>
        /// <param name="curl"></param>
        /// <returns></returns>
        public static bool IsBundle(Bundle bundle, ICurl curl = null)
        {
            if (curl == null)
            {
                curl = SpongeFactory.Create(SpongeFactory.Mode.KERL);
            }


            long totalSum  = 0;
            int  lastIndex = bundle.Length - 1;

            for (int i = 0; i < bundle.Length; i++)
            {
                var tx = bundle.Transactions[i];
                totalSum += tx.Value;

                if (tx.CurrentIndex != i)
                {
                    throw new ArgumentException(Constants.INVALID_BUNDLE_ERROR);
                }
                if (tx.LastIndex != lastIndex)
                {
                    throw new ArgumentException(Constants.INVALID_BUNDLE_ERROR);
                }

                sbyte[] txTrits = Converter.ToTrits(tx.ToTrytes().Substring(2187, 162));
                curl.Absorb(txTrits);

                // continue if output or signature tx
                if (tx.Value >= 0)
                {
                    continue;
                }

                // here we have an input transaction (negative value)
                List <string> fragments = new List <string> {
                    tx.SignatureMessageFragment
                };

                // find the subsequent txs containing the remaining signature
                // message fragments for this input transaction
                for (int j = i; j < bundle.Length - 1; j++)
                {
                    Transaction tx2 = bundle.Transactions[j + 1];

                    // check if the tx is part of the input transaction
                    if (tx.Address.Equals(tx2.Address, StringComparison.Ordinal) && tx2.Value == 0)
                    {
                        // append the signature message fragment
                        fragments.Add(tx2.SignatureMessageFragment);
                    }
                }

                bool valid = new Signing(curl.Clone()).ValidateSignatures(tx.Address, fragments.ToArray(), tx.Bundle);
                if (!valid)
                {
                    throw new ArgumentException(Constants.INVALID_SIGNATURES_ERROR);
                }
            }

            // sum of all transaction must be 0
            if (totalSum != 0)
            {
                throw new ArgumentException(Constants.INVALID_BUNDLE_SUM_ERROR);
            }

            sbyte[] bundleHashTrits = new sbyte[Sponge.HASH_LENGTH];
            curl.Squeeze(bundleHashTrits, 0, Sponge.HASH_LENGTH);
            string bundleHash = Converter.ToTrytes(bundleHashTrits);

            if (!bundleHash.Equals(bundle.Transactions[0].Bundle, StringComparison.Ordinal))
            {
                throw new ArgumentException(Constants.INVALID_BUNDLE_HASH_ERROR);
            }
            return(true);
        }
Exemplo n.º 26
0
        /// <summary>
        /// This function returns the bundle which is associated with a transaction. Input can by any type of transaction (tail and non-tail).
        /// If there are conflicting bundles (because of a replay for example) it will return multiple bundles.
        /// It also does important validation checking (signatures, sum, order) to ensure that the correct bundle is returned.
        /// </summary>
        /// <param name="transaction">the transaction encoded in trytes</param>
        /// <returns>an array of bundle, if there are multiple arrays it means that there are conflicting bundles.</returns>
        public Bundle GetBundle(string transaction)
        {
            Bundle bundle = TraverseBundle(transaction, null, new Bundle());

            if (bundle == null)
            {
                throw new ArgumentException("Unknown Bundle");
            }

            long   totalSum   = 0;
            string bundleHash = bundle.Transactions[0].Bundle;

            curl.Reset();

            List <Signature> signaturesToValidate = new List <Signature>();

            for (int index = 0; index < bundle.Transactions.Count; index++)
            {
                Transaction bundleTransaction = bundle.Transactions[index];
                long        bundleValue       = long.Parse(bundleTransaction.Value);
                totalSum += bundleValue;

                if (long.Parse(bundleTransaction.CurrentIndex) != index)
                {
                    throw new InvalidBundleException("The index of the bundle " + bundleTransaction.CurrentIndex + " did not match the expected index " + index);
                }

                // Get the transaction trytes
                string thisTxTrytes = bundleTransaction.ToTransactionTrytes().Substring(2187, 162);

                // Absorb bundle hash + value + timestamp + lastIndex + currentIndex trytes.
                curl.Absorb(Converter.ToTrits(thisTxTrytes));

                // Check if input transaction
                if (bundleValue < 0)
                {
                    string    address = bundleTransaction.Address;
                    Signature sig     = new Signature();
                    sig.Address = address;
                    sig.SignatureFragments.Add(bundleTransaction.SignatureFragment);

                    // Find the subsequent txs with the remaining signature fragment
                    for (int i = index; i < bundle.Length - 1; i++)
                    {
                        var newBundleTx = bundle[i + 1];

                        // Check if new tx is part of the signature fragment
                        if (newBundleTx.Address == address && long.Parse(newBundleTx.Value) == 0)
                        {
                            sig.SignatureFragments.Add(newBundleTx.SignatureFragment);
                        }
                    }

                    signaturesToValidate.Add(sig);
                }
            }

            // Check for total sum, if not equal 0 return error
            if (totalSum != 0)
            {
                throw new InvalidBundleException("Invalid Bundle Sum");
            }

            int[] bundleFromTrxs = new int[243];
            curl.Squeeze(bundleFromTrxs);
            string bundleFromTxString = Converter.ToTrytes(bundleFromTrxs);

            // Check if bundle hash is the same as returned by tx object
            if (!bundleFromTxString.Equals(bundleHash))
            {
                throw new InvalidBundleException("Invalid Bundle Hash");
            }
            // Last tx in the bundle should have currentIndex === lastIndex
            bundle.Length = bundle.Transactions.Count;
            if (
                !bundle.Transactions[bundle.Length - 1].CurrentIndex.Equals(
                    bundle.Transactions[bundle.Length - 1].LastIndex))
            {
                throw new InvalidBundleException("Invalid Bundle");
            }

            // Validate the signatures
            foreach (Signature aSignaturesToValidate in signaturesToValidate)
            {
                String[] signatureFragments = aSignaturesToValidate.SignatureFragments.ToArray();
                string   address            = aSignaturesToValidate.Address;
                bool     isValidSignature   = new Signing().ValidateSignatures(address, signatureFragments, bundleHash);

                if (!isValidSignature)
                {
                    throw new InvalidSignatureException();
                }
            }

            return(bundle);
        }