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); }
/// <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); } }
/// <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); }
/// <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); }
/// <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); }
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); }
// 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); }
/// <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; } }
/// <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; } }
/// <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; }
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)); }
public bool Search( int security, int offset, int length, ICurl tcurl) { // SearchPrepareTrits(tcurl.State, offset); // return(SearchCpu(tcurl.State, offset, length, security)); }
/// <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); }
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)); }
/// <summary> /// </summary> /// <param name="curl"></param> public Signing(ICurl curl) { // ReSharper disable once ConvertIfStatementToNullCoalescingExpression if (curl == null) { _curl = new Kerl(); } else { _curl = curl; } }
/** * @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); }
/// <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); }
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); } }
/// <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); }
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); }
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); }
/// <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); }
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)); }
/// <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); }
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)); }
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); }
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)); }
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); }
/// <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; } }
/// <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)); }