/// <summary> /// Converts the specified trinary encoded trytes string to trits /// </summary> /// <param name="trytes">The trytes.</param> /// <returns></returns> public static int[] ToTrits(string trytes) { List <int> trits = new List <int>(); if (InputValidator.IsValue(trytes)) { long value = long.Parse(trytes); long absoluteValue = value < 0 ? -value : value; int position = 0; while (absoluteValue > 0) { int remainder = (int)(absoluteValue % Radix); absoluteValue /= Radix; if (remainder > MaxTritValue) { remainder = MinTritValue; absoluteValue++; } trits.Insert(position++, remainder); } if (value < 0) { for (int i = 0; i < trits.Count; i++) { trits[i] = -trits[i]; } } } else { int[] d = new int[3 * trytes.Length]; for (int i = 0; i < trytes.Length; i++) { Array.Copy(TryteToTritsMappings[Constants.TryteAlphabet.IndexOf(trytes[i])], 0, d, i * NumberOfTritsInATryte, NumberOfTritsInATryte); } return(d); } return(trits.ToArray()); }
/// <summary> /// /// </summary> /// <param name="signedBundle"></param> /// <param name="inputAddress"></param> /// <returns></returns> public bool ValidateSignatures(Bundle signedBundle, string inputAddress) { string bundleHash = ""; List <String> signatureFragments = new List <string>(); foreach (var trx in signedBundle.Transactions) { if (trx.Address.Equals(inputAddress)) { bundleHash = trx.Bundle; // if we reached remainder bundle String signatureFragment = trx.SignatureMessageFragment; if (InputValidator.IsNinesTrytes(signatureFragment, signatureFragment.Length)) { break; } signatureFragments.Add(signatureFragment); } } return(ValidateSignatures(inputAddress, signatureFragments.ToArray(), bundleHash)); }
private static bool IsAddressWithChecksum(string addressWithChecksum) { return(InputValidator.IsAddress(addressWithChecksum) && addressWithChecksum.Length == Constants.AddressLengthWithChecksum); }
/// <summary> /// </summary> /// <param name="bundleToSign"></param> /// <param name="inputAddress"></param> /// <param name="keyTrytes"></param> /// <returns></returns> public Bundle AddSignature(Bundle bundleToSign, string inputAddress, string keyTrytes) { // Get the security used for the private key // 1 security level = 2187 trytes var security = keyTrytes.Length / Constants.MessageLength; // convert private key trytes into trits var key = Converter.ToTrits(keyTrytes); // First get the total number of already signed transactions // use that for the bundle hash calculation as well as knowing // where to add the signature var numSignedTxs = 0; for (var i = 0; i < bundleToSign.Transactions.Count; i++) { if (bundleToSign.Transactions[i].Address.Equals(inputAddress)) { if (!InputValidator.IsNinesTrytes(bundleToSign.Transactions[i].SignatureMessageFragment, bundleToSign.Transactions[i].SignatureMessageFragment.Length)) { numSignedTxs++; } // Else sign the transactions else { var bundleHash = bundleToSign.Transactions[i].Bundle; // First 6561 trits for the firstFragment var firstFragment = new int[6561]; Array.Copy(key, firstFragment, 6561); // Get the normalized bundle hash var normalizedBundleFragments = new int[3][]; for (var n = 0; n < 3; n++) { normalizedBundleFragments[n] = new int[27]; } var normalizedBundleHash = bundleToSign.NormalizedBundle(bundleHash); // Split hash into 3 fragments for (var k = 0; k < 3; k++) { Array.Copy(normalizedBundleHash, k * 27, normalizedBundleFragments[k], 0, 27); } // First bundle fragment uses 27 trytes var firstBundleFragment = normalizedBundleFragments[numSignedTxs % 3]; // Calculate the new signatureFragment with the first bundle fragment var firstSignedFragment = _signing.SignatureFragment(firstBundleFragment, firstFragment); // Convert signature to trytes and assign the new signatureFragment bundleToSign.Transactions[i].SignatureMessageFragment = Converter.ToTrytes(firstSignedFragment); for (var j = 1; j < security; j++) { // Next 6561 trits for the firstFragment var nextFragment = new int[6561]; Array.Copy(key, 6561 * j, nextFragment, 0, 6561); // Use the next 27 trytes var nextBundleFragment = normalizedBundleFragments[(numSignedTxs + j) % 3]; // Calculate the new signatureFragment with the first bundle fragment var nextSignedFragment = _signing.SignatureFragment(nextBundleFragment, nextFragment); // Convert signature to trytes and add new bundle entry at i + j position // Assign the signature fragment bundleToSign.Transactions[i + j].SignatureMessageFragment = Converter.ToTrytes(nextSignedFragment); } break; } } } return(bundleToSign); }