/// <summary>
        ///
        /// </summary>
        /// <param name="seed"></param>
        /// <param name="security"></param>
        /// <param name="index"></param>
        /// <param name="checksum"></param>
        /// <param name="curl"></param>
        /// <returns></returns>
        public static string NewAddress(string seed, int security, int index, bool checksum, ICurl curl)
        {
            if (!InputValidator.IsValidSecurityLevel(security))
            {
                throw new ArgumentException(Constants.INVALID_SECURITY_LEVEL_INPUT_ERROR);
            }

            Signing signing = new Signing(curl);

            sbyte[] key          = signing.Key(Converter.ToTrits(seed), index, security);
            sbyte[] digests      = signing.Digests(key);
            sbyte[] addressTrits = signing.Address(digests);

            string address = Converter.ToTrytes(addressTrits);

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

            return(address);
        }
        internal static List <string> SignInputsAndReturn(string seed,
                                                          List <Input> inputs,
                                                          Bundle bundle,
                                                          List <string> signatureFragments, ICurl curl)
        {
            bundle.FinalizeBundle(curl);
            bundle.AddTrytes(signatureFragments);

            //  SIGNING OF INPUTS
            //
            //  Here we do the actual signing of the inputs
            //  Iterate over all bundle transactions, find the inputs
            //  Get the corresponding private key and calculate the signatureFragment
            for (int i = 0; i < bundle.Transactions.Count; i++)
            {
                if (bundle.Transactions[i].Value < 0)
                {
                    string thisAddress = bundle.Transactions[i].Address;

                    // Get the corresponding keyIndex of the address
                    int keyIndex    = 0;
                    int keySecurity = 0;
                    foreach (Input input in inputs)
                    {
                        if (input.Address.StartsWith(thisAddress, StringComparison.Ordinal))
                        {
                            keyIndex    = input.KeyIndex;
                            keySecurity = input.Security;
                            break;
                        }
                    }

                    string bundleHash = bundle.Transactions[i].Bundle;

                    // Get corresponding private key of address
                    sbyte[] key = new Signing(curl).Key(Converter.ToTrits(seed), keyIndex, keySecurity);

                    //  First 6561 trits for the firstFragment
                    //sbyte[] firstFragment = ArrayUtils.SubArray2(key, 0, 6561);

                    //  Get the normalized bundle hash
                    sbyte[] normalizedBundleHash = bundle.NormalizedBundle(bundleHash);

                    //  First bundle fragment uses 27 trytes
                    //sbyte[] firstBundleFragment = ArrayUtils.SubArray2(normalizedBundleHash, 0, 27);

                    //  Calculate the new signatureFragment with the first bundle fragment
                    //sbyte[] firstSignedFragment =
                    //    new Signing(curl).SignatureFragment(firstBundleFragment, firstFragment);

                    //  Convert signature to trytes and assign the new signatureFragment
                    //bundle.Transactions[i].SignatureMessageFragment = Converter.ToTrytes(firstSignedFragment);


                    // if user chooses higher than 27-tryte security
                    // for each security level, add an additional signature
                    for (int j = 0; j < keySecurity; j++)
                    {
                        int hashPart = j % 3;
                        //  Add parts of signature for bundles with same address
                        if (bundle.Transactions[i + j].Address.StartsWith(thisAddress, StringComparison.Ordinal))
                        {
                            // Use 6562 trits starting from j*6561
                            sbyte[] keyFragment = ArrayUtils.SubArray2(key, 6561 * j, 6561);

                            // The current part of the bundle hash
                            sbyte[] bundleFragment =
                                ArrayUtils.SubArray2(normalizedBundleHash, 27 * hashPart, 27);

                            //  Calculate the new signature
                            sbyte[] signedFragment = new Signing(curl).SignatureFragment(bundleFragment,
                                                                                         keyFragment);

                            //  Convert signature to trytes and assign it again to this bundle entry
                            bundle.Transactions[i + j].SignatureMessageFragment =
                                (Converter.ToTrytes(signedFragment));
                        }
                    }
                }
            }

            List <string> bundleTrytes = new List <string>();

            // Convert all bundle entries into trytes
            foreach (Transaction tx in bundle.Transactions)
            {
                bundleTrytes.Add(tx.ToTrytes());
            }

            bundleTrytes.Reverse();
            return(bundleTrytes);
        }
示例#3
0
 /// <summary>
 /// </summary>
 /// <param name="curl"></param>
 public Multisig(ICurl curl)
 {
     _curl = curl;
     _curl.Reset();
     _signing = new Signing();
 }
示例#4
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);
        }