public async Task TestAddressHasInvalidTransactionsShouldBeSkippedAndReturnValidData()
        {
            var contactAddress = new Address(Seed.Random().Value);
            var ntruKey        = InMemoryContactRepository.NtruKeyPair.PublicKey;

            var publicKeyTrytes     = ntruKey.ToBytes().EncodeBytesAsString();
            var requestAdressTrytes = new TryteString(publicKeyTrytes + Constants.LineBreak + contactAddress.Value + Constants.End).Concat(new Fragment())
                                      .Concat(new Fragment());

            var invalidBundle = CreateBundle(new TryteString("999999999999999"));
            var validBundle   = CreateBundle(requestAdressTrytes);

            var messenger = new Mock <IMessenger>();

            messenger.Setup(r => r.GetMessagesByAddressAsync(It.IsAny <Address>())).ReturnsAsync(
                new List <Message>
            {
                new Message(invalidBundle.Transactions[0].ToTrytes()),
                new Message(validBundle.Transactions.Aggregate(new TryteString(), (current, tryteString) => current.Concat(tryteString.Fragment)))
            });

            var repository = new ContactRepositoryStub(messenger.Object, new SignatureValidatorStub());
            var contact    = await repository.LoadContactInformationByAddressAsync(new Address());

            Assert.AreEqual(contactAddress.Value, contact.ContactAddress.Value);
            Assert.AreEqual(ntruKey.ToString(), contact.PublicKey.ToString());
        }
示例#2
0
        public async Task TestAddressHasInvalidTransactionsShouldBeSkippedAndReturnValidData()
        {
            var contactAddress = new Address(Seed.Random().Value);
            var ntruKey        = InMemoryContactRepository.NtruKeyPair.PublicKey;

            var publicKeyTrytes     = ntruKey.ToBytes().EncodeBytesAsString();
            var requestAdressTrytes = new TryteString(publicKeyTrytes + Constants.LineBreak + contactAddress.Value + Constants.End);

            var invalidBundle = CreateBundle(new TryteString("999999999999999"));
            var validBundle   = CreateBundle(requestAdressTrytes);

            var iotaRepository = new Mock <IIotaRepository>();

            iotaRepository.Setup(r => r.FindTransactionsByAddressesAsync(It.IsAny <IEnumerable <Address> >())).ReturnsAsync(
                new TransactionHashList {
                Hashes = new List <Hash> {
                    invalidBundle.Hash, validBundle.Hash
                }
            });

            iotaRepository.SetupSequence(r => r.GetBundleAsync(It.IsAny <Hash>())).ReturnsAsync(invalidBundle).ReturnsAsync(validBundle);

            var repository = new ContactRepositoryStub(iotaRepository.Object);
            var contact    = await repository.LoadContactInformationByAddressAsync(new Address());

            Assert.AreEqual(contactAddress.Value, contact.ContactAddress.Value);
            Assert.AreEqual(ntruKey.ToString(), contact.NtruKey.ToString());
        }
示例#3
0
        public MaskedAuthenticatedMessage CreateMessage(TryteString message)
        {
            var tree         = this.TreeFactory.Create(this.Seed, this.Start, this.Count, this.SecurityLevel);
            var nextRootTree = this.TreeFactory.Create(this.Seed, this.Start + this.Count, this.NextCount, this.SecurityLevel);

            var maskedAutheticatedMessage = this.MamFactory.Create(
                tree,
                this.Index,
                message,
                nextRootTree.Root.Hash,
                this.Key,
                this.Mode,
                this.SecurityLevel);

            if (this.Index == this.Count - 1)
            {
                this.Start = this.NextCount + this.Start;
                this.Index = 0;
            }
            else
            {
                this.Index++;
            }

            this.NextRoot = maskedAutheticatedMessage.NextRoot;

            return(maskedAutheticatedMessage);
        }
示例#4
0
        /// <inheritdoc />
        public async Task <SendMessageResponse> ExecuteAsync(SendMessageRequest request)
        {
            if (request.Message.Length > Constants.MessageCharacterLimit)
            {
                return(new SendMessageResponse {
                    Code = ResponseCode.MessageTooLong
                });
            }

            var messageTimestamp = TryteString.FromUtf8String(DateTime.UtcNow.ToString(CultureInfo.InvariantCulture));
            var senderId         = request.UserPublicKeyAddress.GetChunk(0, 30);
            var encryptedMessage = await Task.Run(
                () => new NtruKeyExchange(NTRUParamSets.NTRUParamNames.E1499EP1).Encrypt(
                    request.KeyPair.PublicKey,
                    Encoding.UTF8.GetBytes(request.Message)));

            var encryptedPayload = new TryteString(encryptedMessage.EncodeBytesAsString());
            var payloadSignature = Constants.FirstBreak.Concat(senderId).Concat(Constants.SecondBreak).Concat(messageTimestamp);

            var firstMessagePartPayload  = encryptedPayload.GetChunk(0, 2070).Concat(payloadSignature).Concat(new TryteString("A")).Concat(Constants.End);
            var secondMessagePartPayload = new TryteString(encryptedPayload.Value.Substring(2070)).Concat(payloadSignature).Concat(new TryteString("B"))
                                           .Concat(Constants.End);

            await this.Messenger.SendMessageAsync(new Message(MessageType.ChatMessage, firstMessagePartPayload, request.ChatAddress));

            await this.Messenger.SendMessageAsync(new Message(MessageType.ChatMessage, secondMessagePartPayload, request.ChatAddress));

            return(new SendMessageResponse {
                Code = ResponseCode.Success
            });
        }
示例#5
0
        public static async Task <List <Contact> > GetPublicKeysAndContactAddresses(TangleMessenger tangleMessenger, string receiverAddress, bool dontLoadSql = false)
        {
            var trytes = await tangleMessenger.GetMessagesAsync(receiverAddress, 3, false, dontLoadSql);

            var contacts = new List <Contact>();

            foreach (var tryte in trytes)
            {
                var trytesString = tryte.Message.ToString();
                if (!trytesString.Contains(ChiotaConstants.LineBreak))
                {
                    continue;
                }

                try
                {
                    var index           = trytesString.IndexOf(ChiotaConstants.LineBreak, StringComparison.Ordinal);
                    var publicKeyString = trytesString.Substring(0, index);
                    var bytesKey        = new TryteString(publicKeyString).DecodeBytesFromTryteString();

                    contacts.Add(
                        new Contact
                    {
                        NtruKey        = new NTRUPublicKey(bytesKey),
                        ContactAddress = trytesString.Substring(index + ChiotaConstants.LineBreak.Length, 81)
                    });
                }
                catch
                {
                    // ignored
                }
            }

            return(RemoveDuplicateContacts(contacts));
        }
示例#6
0
        public void TestToBytesDoesGenerateCorrectLength()
        {
            var tryteString = new TryteString("FFWEHDTAQFFDNEUGLAIDHHSAEHTGEDQEVBGHVHGFLCWDM9L99GOFWAA99EDBQCJCACZEZAC9UEYGZ9Q9DFNBEDRB9GGAZAV9VH9FTAODRAMGMDSHUGX9LH9HVBOFRBLENFN9YEEFVGI9QDJBF9KHCH9IEFYAZHMBPDEFNDHBPBLACHEIAECBZFHHLAQBCILGEDQDAB9HVDOFNBXFMBNHVFOBZA9CIGCCGHO9DCUDFEFCPFIHJDK9VDTGRGGEF9CBVDQAAECERF9D9CYHCHPBDFTDXEFEN9EEOBFHXDBBPANCPBVDTGGFUGGHXGACKBF9M9FHMFKDR9GCRBEAFFWEKB9IMBTALFKDXBBAPEXETCZCM9B9QECBGDKCQDNEDF9BDFLCX9YHMG9HC9MDSCCBSCKATCD9VAFHPHZDG9DCTD9FYGP9WE9GHIL9BHNGSEC9E9WCKHIDYFY9EBWEQBYHXCO9HFQHWFTDODIDKHDCMFMCLBVCVAH99FECEIEGOFKCC9N9Y9GEN9LGZCIGDDAARHEI9BGGSBGFJEBFJFLHOH9HF9U9QAGCLBQAECBIBATEJIWDNDKGVCLIVGABKFEBXCADQHY9L9MFCFT9LETCXASFEF9GWCMH9DTAQDIACEZBR9XABAZEZBZCKCG9FBIDVELEDETANHFCLCVFEGFDT9GD9E9FJ9Y9FFJAWGAID9UDLDQAEFIAMAXCW99IWAVBM9DAZEQ9ZHKBYEOESBABJEYE9AGFZDEGG9MGXAEBVEYESCIGBFGAGHKIGIY9RBVBDFTELFICQEMASEUBAHNCUCJEC9BAGBECVFTCVELBC9SHICKAF9KAMDVBT9V9X9YBCHHCQFOBCFLDICLAXEKER9IFACCAIIRGB9VFMDWCTGRFQHXDQHL9T9FGIIICA9E9UFRAWALGZEBHOBPCNCK9LEKIBHZAJHUBGICBLBCDUHNAQHJBJ9KGS9TEGEXHBGEHBBSEJBRBJANDB9GGRDCGZBRFTETEK9IEK9TDZBABUFE9IGABEDTFGFDGBFXHECY9Z9ZBCD9DOCJCCBWHQGJHCALATHB9VDYC9CDHAGB9GC9B9HEEBCHCIEUGHFJHCGLEUFDDAGKFG9SCXBLHUCV9ADPESBXBLFRFLGKHZGZBZEXFMES9CBHAEHQGWCVBZFKFM9IHYHRA9GPAL9NAV9AEJHGILAQDKDICJHRAABUDN9YGKHBIGAG9ICIIYEZ9WGCANHCGBEBCBGQBJCN9EGFCLAIBCDHHHHRFR9D9DGEALCPAECDEY9LFIFFIEEJDHEDDF9JGVHAISDW9NBFAQ9IA9FNAZH9EY9AEDCY9NHS9TEJ9AEQFCEGFHGHFYGNFQAVHAHT9EFXHWAIBVCFGJFLHAD9AKAXE9HAHVCWAIFIBAFVBC9PBDBVFDAT9LFKFCACEKFACUEHDHEHDOBSFSHJEACODUFKDPCVCMHEAHHJBDBGGPBHFIASBJDJIGGGFGFIEJ9XBABQEEBLFSAGAYFK9AIYFCFBIEESDZCXDFFUDVGHAFEFDJGAISELIVFAADDPCFCICLBKHDHIEIEGHG9KCTETDFCGEN9VCV9ACYELAVERHPFLIT9KDYFQHOBH9PFEAIIFIMBDALECECDTBCGOCLGUCK9SBFALHRETFV9GGQHTGKAGELHOEYGYHECCFZCNCIHDIF9TGOBVCVDWCXHQFYDDEAISGGATEPEHGW9LFAITEYCYDMG9DRGFAYCJ9OCVHWHLAGBRHKIFIY9JFTFSCV9PAVHTFA9A999EGIAAIEHPEECCBWDM9OCAADFIAWFAGSDJGOAVCCD9ACADHIIMGJGP9OCNGIDNDSCHCX9IEMCLATGBEKGZFXGDFYABGE9LEN9RAJIMASBI9YATHREFDNEYDFCLEDFGCKAIFDCODFEOBCDPDIGO9Y9DHUAADAFBAZE99UHBEUGQAVDK99COGT9XATGLIMFSEYDD9XCYBJ9FGXANAWDJ9C9GFCAXAGEBDGFLEODVAM9MFSHTBTGJHEDC9GCIBLCSBKCNGHA99");
            var bytes       = tryteString.ToBytes();

            Assert.AreEqual(1022, bytes.Length);
        }
示例#7
0
        public void TestUtf8StringConversion()
        {
            var stringValue = "┬";
            var tryteString = TryteString.FromUtf8String(stringValue);

            Assert.AreEqual(stringValue, tryteString.ToUtf8String());
        }
示例#8
0
        public static byte[] DecodeBytesFromTryteString(this TryteString tryteString)
        {
            var trytesArray = new List <string> {
                "9", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"
            };

            // If input length is odd, return null
            if (tryteString.Value.Length % 2 != 0)
            {
                return(null);
            }

            var byteList = new List <byte>();

            for (var i = 0; i < tryteString.Value.Length; i += 2)
            {
                var firstValue  = trytesArray.IndexOf(tryteString.Value.Substring(i, 1));
                var secondValue = trytesArray.IndexOf(tryteString.Value.Substring(i + 1, 1));

                var value = firstValue + (secondValue * 27);
                byteList.Add(Convert.ToByte(value));
            }

            return(byteList.ToArray());
        }
        public async Task TestIndexHasBeenWrittenFromAnotherSourceShouldSkipIndex()
        {
            var seed = Seed.Random();

            // Publish a message as if it was published from another app
            var tempProvider = new InMemoryDeterministicSeedManager(
                new InMemoryResourceTracker(),
                new IssSigningHelper(new Curl(), new Curl(), new Curl()),
                new AddressGenerator(),
                IotaResourceProvider.Repository);

            var credentials = await tempProvider.CreateChannelCredentialsAsync(seed);

            var channel = new MamChannelFactory(CurlMamFactory.Default, CurlMerkleTreeFactory.Default, IotaResourceProvider.Repository).Create(
                Mode.Restricted,
                credentials.Seed,
                IotaFhirRepository.SecurityLevel,
                credentials.ChannelKey);

            var message = channel.CreateMessage(TryteString.FromAsciiString("Test"));
            await channel.PublishAsync(message, 14, 1);

            // Create credentials that should skip the first index
            var provider = new InMemoryDeterministicSeedManager(
                new InMemoryResourceTracker(),
                new IssSigningHelper(new Curl(), new Curl(), new Curl()),
                new AddressGenerator(),
                IotaResourceProvider.Repository);

            await provider.CreateChannelCredentialsAsync(seed);

            Assert.AreEqual(1, provider.CurrentIndex);
        }
示例#10
0
        private async Task <GetContactsResponse> CrossCheckAsync(
            IAsymmetricKeyPair keyPair,
            TryteString publicKeyAddress,
            List <Contact> approvedContacts,
            IEnumerable <Contact> pendingContactRequests)
        {
            var pending = new List <Contact>();

            foreach (var contactRequest in pendingContactRequests)
            {
                var requestedContactsMessages = await this.Messenger.GetMessagesByAddressAsync(new Address(contactRequest.ContactAddress));

                if (this.TryParseNonces(keyPair, requestedContactsMessages))
                {
                    await this.ContactRepository.AddContactAsync(contactRequest.ChatAddress, true, publicKeyAddress.Value);

                    approvedContacts.Add(contactRequest);
                }
                else
                {
                    pending.Add(contactRequest);
                }
            }

            return(new GetContactsResponse {
                ApprovedContacts = approvedContacts, PendingContactRequests = pending, Code = ResponseCode.Success
            });
        }
示例#11
0
        public void TestTransferMessageDoesNotFitIntoOneTransactionShouldCreateSecondTransaction()
        {
            var transfer = new Transfer
            {
                Address = new Address("RBTC9D9DCDEAUCFDCDADEAMBHAFAHKAJDHAODHADHDAD9KAHAJDADHJSGDJHSDGSDPODHAUDUAHDJAHAB")
                {
                    Balance = 42
                },
                Message = TryteString.FromString(GetSuperLongMessage()),
                Tag     = Tag.Empty
            };

            var bundle = new Bundle();

            bundle.AddTransaction(transfer.Address, transfer.Message, transfer.Tag, 999999999L);

            Assert.AreEqual(2, bundle.Transactions.Count);

            var transactionOne = bundle.Transactions[0];

            Assert.AreEqual(transfer.Address, transactionOne.Address);
            Assert.AreEqual(transfer.Tag, transactionOne.Tag);
            Assert.AreEqual(transfer.Address.Balance, transactionOne.Value);

            var transactionTwo = bundle.Transactions[1];

            Assert.AreEqual(transfer.Address, transactionTwo.Address);
            Assert.AreEqual(transfer.Tag, transactionTwo.Tag);
            Assert.AreEqual(0, transactionTwo.Value);
        }
示例#12
0
        /// <inheritdoc />
        public MaskedAuthenticatedMessage Create(
            MerkleTree tree,
            int index,
            TryteString message,
            Hash nextRoot,
            TryteString channelKey,
            Mode mode,
            int securityLevel)
        {
            var nextRootTrits = nextRoot.ToTrits();

            var messageTrits       = message.ToTrits();
            var indexTrits         = Pascal.Encode(index);
            var messageLengthTrits = Pascal.Encode(messageTrits.Length);

            var subtree = tree.GetSubtreeByIndex(index);

            this.Curl.Reset();
            this.Curl.Absorb(channelKey.ToTrits());
            this.Curl.Absorb(tree.Root.Hash.ToTrits());

            var payload = new List <int>();

            payload.InsertRange(0, indexTrits);
            payload.InsertRange(indexTrits.Length, messageLengthTrits);

            var nextRootStart = indexTrits.Length + messageLengthTrits.Length;

            this.Curl.Absorb(payload.Take(nextRootStart).ToArray());

            // encrypt next root together with message trits
            payload.InsertRange(nextRootStart, this.Mask.Mask(nextRootTrits.Concat(messageTrits).ToArray(), this.Curl));

            // calculate message end and add nonce
            var messageEnd = nextRootStart + nextRootTrits.Length + messageTrits.Length;

            this.AddNonce(securityLevel, messageEnd, payload);

            // create signature, encrypt signature + sibling count (get trits from pascal) + siblings
            var signature          = this.SigningHelper.Signature(this.Curl.Rate(Constants.TritHashLength), subtree.Key.ToTrits());
            var subtreeTrits       = subtree.ToTryteString().ToTrits();
            var siblingsCount      = subtreeTrits.Length / Constants.TritHashLength;
            var encryptedSignature = this.Mask.Mask(signature.Concat(Pascal.Encode(siblingsCount)).Concat(subtreeTrits).ToArray(), this.Curl);

            // insert signature and pad to correct length (% 3 == 0)
            payload.InsertRange(messageEnd + NonceLength, encryptedSignature);
            PadPayload(payload);

            this.Curl.Reset();

            var messageAddress = this.GetMessageAddress(tree.Root.Hash, mode);

            return(new MaskedAuthenticatedMessage
            {
                Payload = CreateBundleFromPayload(messageAddress, payload),
                Root = tree.Root.Hash,
                Address = messageAddress,
                NextRoot = nextRoot
            });
        }
        /// <summary>
        /// The execute.
        /// </summary>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        public async Task Execute()
        {
            var seed       = Seed.Random();
            var channelKey = Seed.Random();

            // To send a message we first create a channel via factory. Note that only one seed should be used per channel
            // If your channel key is not an ASCII string, create the channel like this this.ChannelFactory.Create(Mode.Restricted, seed, SecurityLevel.Medium, channelKey.Value, true);
            var channel = this.ChannelFactory.Create(Mode.Restricted, seed, SecurityLevel.Medium, channelKey.Value);

            // Creating a message is rather easy. The channel keeps track of everything internal
            var message = channel.CreateMessage(TryteString.FromAsciiString("This is my first message with MAM from CSharp!"));

            // Nevertheless we still need to publish the message after creating it
            await channel.PublishAsync(message);

            // Creating a message is rather easy. The channel keeps track of everything internal
            var message2 = channel.CreateMessage(TryteString.FromAsciiString("This is my second message with MAM from CSharp!"));

            // Nevertheless we still need to publish the message after creating it
            await channel.PublishAsync(message2);

            Console.WriteLine($"Seed: {seed.Value}");
            Console.WriteLine($"ChannelKey: {channelKey.Value}");
            Console.WriteLine($"Root: {message.Root.Value}");
        }
示例#14
0
        public static Contact FilterRequestInfos(IEnumerable <TryteString> trytes)
        {
            var contact            = new Contact();
            var oneKeyAlreadyFound = false;

            foreach (var tryte in trytes)
            {
                var trytesString = tryte.ToString();
                if (!trytesString.Contains("9CHIOTAYOURIOTACHATAPP9"))
                {
                    continue;
                }

                if (oneKeyAlreadyFound)
                {
                    return(null);
                }

                var index           = trytesString.IndexOf("9CHIOTAYOURIOTACHATAPP9", StringComparison.Ordinal);
                var publicKeyString = trytesString.Substring(0, index);
                var bytesKey        = new TryteString(publicKeyString).ToBytes();

                contact.PublicNtruKey = new NTRUPublicKey(bytesKey);

                contact.ContactAdress = trytesString.Substring(index + 23, 81);
                oneKeyAlreadyFound    = true;
            }

            return(contact);
        }
示例#15
0
        public static List <ChatMessage> FilterChatMessages(IEnumerable <TryteString> trytes, NtruKex ntruKex, IAsymmetricKeyPair keyPair)
        {
            var chatMessages = new List <ChatMessage>();

            foreach (var tryte in trytes)
            {
                try
                {
                    var trytesString  = tryte.ToString();
                    var indexBreak    = trytesString.IndexOf("9CHIOTAYOURIOTACHATAPP9", StringComparison.Ordinal);
                    var messageTrytes = new TryteString(trytesString.Substring(0, indexBreak));
                    var dateTrytes    = new TryteString(trytesString.Substring(indexBreak + 23, trytesString.Length - indexBreak - 23));

                    // can only decrypt messages from other user (send with own public key)!
                    var decryptedMessage = ntruKex.Decrypt(keyPair, messageTrytes.ToBytes());
                    var date             = DateTime.Parse(dateTrytes.ToUtf8String());
                    var chatMessage      = new ChatMessage {
                        Message = decryptedMessage, Date = date
                    };
                    chatMessages.Add(chatMessage);
                }
                catch
                {
                    continue;
                }
            }

            return(chatMessages);
        }
示例#16
0
        public async Task <bool> SendMessageAsync(TryteString message, string address, int retryNumber = 3)
        {
            var roundNumber = 0;

            while (roundNumber < retryNumber)
            {
                //this.UpdateNode(roundNumber);

                var bundle = new Bundle();
                bundle.AddTransfer(CreateTransfer(message, address));

                try
                {
                    await this.Repository.SendTransferAsync(this.seed, bundle, SecurityLevel.Medium, Depth, this.MinWeight);

                    return(true);
                }
                catch (Exception e)
                {
                    Trace.WriteLine(e);
                    roundNumber++;
                }
            }

            return(false);
        }
示例#17
0
        public void TestAggregateTransactions()
        {
            var fragmentOne = TryteString.FromUtf8String("TestFragmentOne");
            var fragmentTwo = TryteString.FromUtf8String("TestFragmentTwo");

            var bundle = new Bundle();

            bundle.AddTransfer(new Transfer
            {
                Address =
                    new Address("RBTC9D9DCDEAUCFDCDADEAMBHAFAHKAJDHAODHADHDAD9KAHAJDADHJSGDJHSDGSDPODHAUDUAHDJAHAB"),
                Message = fragmentOne,
                Tag     = Tag.Empty
            });
            bundle.AddTransfer(new Transfer
            {
                Address =
                    new Address("RBTC9D9DCDEAUCFDCDADEAMBHAFAHKAJDHAODHADHDAD9KAHAJDADHJSGDJHSDGSDPODHAUDUAHDJAHAB"),
                Message = fragmentTwo,
                Tag     = Tag.Empty
            });

            var expectedPayload = bundle.Transactions[0].Fragment.Concat(bundle.Transactions[1].Fragment);

            Assert.AreEqual(expectedPayload.Value, bundle.AggregateFragments().Value);
        }
示例#18
0
        public override async Task <PublishVerifiableClaimsReply> PublishVerifiableClaims(PublishVerifiableClaimsRequest request, ServerCallContext context)
        {
            m_logger.LogInformation("PublishVerifiableClaims start");
            try
            {
                var channel         = m_mamChannelFactory.Create(Mode.Restricted, new Seed(request.Seed), securityLevel: SecurityLevel.Medium, channelKey: request.SideKey, keyIsTrytes: true);
                var attestationJson = CreateAttestationFromRequest(request);
                m_logger.LogInformation($"Remove before production! PublishVerifiableClaims Attestation JSON={attestationJson}");
                var message = channel.CreateMessage(TryteString.FromUtf8String(attestationJson));

                await channel.PublishAsync(message, minWeightMagnitude : 10);

                m_logger.LogInformation($"Remove before production! PublishVerifiableClaims Message={JsonSerializer.Serialize(message)}");


                return(CreatePublishVerifiableClaimsReplyFromMessage(message));
            }
            catch (Exception ex)
            {
                m_logger.LogError("CreateVerifiableClaims", ex);

                throw new RpcException(new Status(StatusCode.NotFound, ex.Message));
            }
            finally
            {
                m_logger.LogInformation("PublishVerifiableClaims end");
            }
        }
示例#19
0
 /// <summary>
 /// The init.
 /// </summary>
 /// <param name="messageRoot">
 /// The message root.
 /// </param>
 /// <param name="mode">
 /// The mode.
 /// </param>
 /// <param name="channelKey">
 /// The channel key.
 /// </param>
 /// <param name="nextRoot">
 /// The next Root.
 /// </param>
 public void Init(Hash messageRoot, Mode mode, TryteString channelKey = null, Hash nextRoot = null)
 {
     this.MessageRoot = messageRoot;
     this.Mode        = mode;
     this.Key         = channelKey;
     this.NextRoot    = nextRoot;
 }
示例#20
0
        public void TestTransferMessageDoesNotFitIntoOneTransactionShouldCreateSecondTransaction()
        {
            var transfer = new Transfer
            {
                Address =
                    new Address("RBTC9D9DCDEAUCFDCDADEAMBHAFAHKAJDHAODHADHDAD9KAHAJDADHJSGDJHSDGSDPODHAUDUAHDJAHAB"),
                Message         = TryteString.FromAsciiString(GetSuperLongMessage()),
                Tag             = Tag.Empty,
                ValueToTransfer = 42
            };

            this.bundle = new Bundle();
            this.bundle.AddTransfer(transfer);

            Assert.AreEqual(2, this.bundle.Transactions.Count);

            var transactionOne = this.bundle.Transactions[0];

            Assert.AreEqual(transfer.Address, transactionOne.Address);
            Assert.AreEqual(transfer.Tag, transactionOne.Tag);
            Assert.AreEqual(transfer.ValueToTransfer, transactionOne.Value);

            var transactionTwo = this.bundle.Transactions[1];

            Assert.AreEqual(transfer.Address, transactionTwo.Address);
            Assert.AreEqual(transfer.Tag, transactionTwo.Tag);
            Assert.AreEqual(0, transactionTwo.Value);
        }
        /// <summary>
        /// The load contact information from tangle.
        /// </summary>
        /// <param name="transactionHashes">
        /// The transaction hashes on address.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        private async Task <TryteString> LoadRawContactInformationFromTangle(IEnumerable <Hash> transactionHashes)
        {
            TryteString latestContactInformation = null;

            foreach (var transactionHash in transactionHashes)
            {
                var contactInformationBundle = await this.IotaRepository.GetBundleAsync(transactionHash);

                var bundleTrytes = contactInformationBundle.Transactions.Aggregate(
                    new TryteString(),
                    (current, tryteString) => current.Concat(tryteString.Fragment));

                if (!bundleTrytes.Value.Contains(Constants.End) || !bundleTrytes.Value.Contains(Constants.LineBreak))
                {
                    continue;
                }

                if (latestContactInformation == null)
                {
                    latestContactInformation =
                        new TryteString(bundleTrytes.Value.Substring(0, bundleTrytes.Value.IndexOf(Constants.End, StringComparison.Ordinal)));
                }
                else
                {
                    throw new MessengerException(ResponseCode.AmbiguousContactInformation);
                }
            }

            return(latestContactInformation);
        }
示例#22
0
        public void TestRestrictedMessageCreation32Bit()
        {
            var expectedPayload = new Bundle();

            expectedPayload.AddTransfer(new Transfer
            {
                Address   = new Address(),
                Message   = new TryteString("AQRAQLYEXHTXQUVYAXBDJZFWM9QPHXNQRVVGEODVNZAQMPXIHVYDFLHKDBFLSEUDGHVGNYFLEBQTJORJ9BDWXYUBYQDBKYHXGCIRVRJLLRQCBFSYYFTRVRPYJTHIIOOFDISBILGHQCWXSNLRXRKPTBSBO9ENPHHCSTPGFEVK9GVOWCBTJKVRANFBPHEOQNTJJQNYWQSYYRXZMFHADWUQJVBOLP9BUV9PXUIAKDUGRICOLQXXSXNGNMUMBWJRJDBSUJWSPGLXMHBLUUSSWSQUTSWKRRPWURYJYHRHSRCLBEBMHKVFJMLYDDEIHHBCAZYLLNGMFTUSUZA9VAWSSFSKLDIFYDDZJXJZ9VRIADVEAPMRBBUAOJCWCWMBUEVGBFMXPHQEE9JNPLLSDBDJSLXZXISGDOAMGQSVMOMKOWTWJPYCDKXRRBBKLPJRJMN9LJZQZADQQYXNBNFQDBITXBXPSMWDNNJAODPSEJRQZCKTLSOLUIMOWXZHYXJOXAGRJC9NNGWLYY9VQYW9IYFCQWDZQJDNWHVIXEIYSHTSOGRHMPQZ9YUTWDCRUEZGJTKVDRFNZVRBVAJBBNHILDFSBPNJKBUVXW9CDOEGVFPAWUZROYEBYT9NHI9DNGLHWPSKMJELJSMVTRNGEJNAMNEWUQ9GSRANMRIEB9GWXJD9GX9EHTRNYEYZJFKALYJVPUITHKGMM9QJDOKHWXQ9YN9ZBBCRNESWWBPWZIQVGWDQSRVROIRTPK9STFWRDDUFDKSLQQOXRWSSQCOHIJUJLPOBUVNWLOGGXDMEFOQHXSGQOZVQGYLUABLBJHXZRRIB9ZTLAXHHSRHAODYTSDTJUGRWVDJAJNRNDL9YVEPKLVAQFPAONMKOHHCLAZWFTAZTMEQKGNMNBYHBGNNOV99HCMQDRZEGGPAWA9FFO9SESTP9TSFXLCYPJJ9JKROY99VVHENCHSSSXKDAFRGOKAKIWCOHXYNFPKKWCBSGENRBX9FQFBITIO9999USHGAMQMBYPYPQANDGZXIPYVFZCTRGALNR9XGZBYAKQYIJDSBTWHIJQMOVOVBVCRUXZD9IGMODZPXLGTKYOWRVQC9YYVVBVMDRSUUPJDJUMLNCPGZJLTGQPQOXKGKUWASQQ9AER9JLWMQA9GLPATMVRDFIWLC9GBIKRXGJSZLPZVKGTWIIDCGXIDKMLQTCWTPICN9UZZXEOFFCQSJPOXFSCEHJNGIGOYIFZFMPWHJOFZGIYRFWOZCSSHKPWHDEELMN9ZWULHRMRHVNGTNUEZEMRINSVYEGBOJMNYFWNLFSIHHRIFXZRLEGFIEOT9WYZQXFTKXRAYRRKDV9VYUBSZAKARAIZYDWBEDLLOCAXQZIXSIRFGCGZWVRRCME9TXPTDUYLYUGLIBENQ99SDQLYFBJZHGQYQBLJMLFZLQLPHYMCFMTOSDA99DXAMCEAMBGNFFDJIKTUCBHSYKH9KLRVBYXOJJYKZYXJLIKIZFQHNFWWNCQACXZIXDLJXNU9UNZQJMFLJJXGSEPXIFRDKSUENGGELMFPVQKHAYPHMIPHVKZTNFTWMERRTVFHJLKILHRX9XSVYJZQKQXIMIMPDGCNXZKXUBNZOVXMCZXGXZTVBTIQUZ9GDQJGIHFKFXYZHDNGPIUXLIKSDBQQNMJCVRJUKQVJWGOFOBTXDSFLM9BGYZJREIBUBEVCOME9NNKHFEKWGJRTMZFDHFZY9YHTFJNCNZBGMVEEKUYPZBYQQFVVZEFSQDXOWTNUSU9GUTS9ITJAYYELPZYITWELVOAKMPTUIL9UJD9TN9HVLIYWAHMQBIHLUSBRSAGXQRAOOKGIBYMM9AOLC9DQVMNFMPGDSQUTWMRKVKE9FRZNCQJDVDKBINILRFKBEEDZTWI9UUCNLIMT9MLQRMBRJQLKHJXEKWJDEK9WAKXUJVWMUNLBUSVYSUZDOIEJAKZZOWPQFNKDLPDICGTQKOSBPWKHGPBUWYXWYVPIOIELDLIBPI9FJRSHVEKRNMQ9VPOCCCASWKL99TZCFNHLHVMOOFNBGSRXYKCKJOLNEBYAFCRMDHOVWUZ9MIFDSRRFSHSIWIN9WLLXMOKCXYTTESFZUNMQAHYVOVQQH9YZVOQATUPEPGCCGTPBAAOSPJ9ALPYXONR9OCODZDJPNPMQIREEXICFQIWRZ99OPS9ALP9GLPTTWGRJHATSJJTEKFZDJYEUKBIAACLOALTSXWCCL9GBUTWIXVEW9HYLVKRRRAATNYMGSAKLUN9HJQPIMXJOYIDXNONMHXZUGXOFIQIFBTPYDXXMKOAUUNOJU9IIXFLSSWKOCRJKXNWKKAMJRMFYSMAOWSCI9NTRQKT99CIDHJMZWSDKAIKOYWHSCJZRQWWDZOC9TKXHXCDN9GTMMGXXHXIJFMTCQFTDAKPEPQLNVCIE9UMIYXHDQUGPJSHPMRFCHMPGOYHVATXBIGOCZAFDNTVMJRJIVQDLNQYNSASMLXPSFUMYBGHXTCFYDLOGOCDTWPZMVPKMP9EEXEKNMSTEQKFZIVU9DKHSEQA9XQNOKUK9ABSTZ9XRPDMDECMYRRGSYHEZDAWEDGTQSMRC9DQ9FUWS9QELTDYZCRFYABZKVLCFGVKYGYIWJGNQKI9ONMXWFJNFIEPZRSSLNUUQOXK9YXQYMWR9B9UAUXYYONKYUG9JAJOUMLKQOXBD9JBLAQHXBJINNLBXKYGYLPRLASOFISEFXG9KENN9YFFP9J9NVVYKAEFAUTIQRDTVKVHQYEWJOGQEUPSWEIMYWYYEZRGJUEDAHDYPQEGX9KTUODLORTCJZGJCKFGEJTWRGEACRRINEQBUWS9NUPP9BMONGQQABVGBLRQXZJYXDHS9DFWAWLOZVKSDZD9UGBPKDCHLYEAUOABXKMNWTSUZTHTZBYOALUHQHSEK9WPGWGVNQEGVDDFZJXLAYINRUQYQBROPB9RGAFWMPOBOANCGW9DJJ9NUIHLQE9RNZOHLPYAIACONJXYFRBAOVJEWOTO9HZCZOVJGHQOGGJAB9QUWDRI9KLX9EGOHGTJIYQHTTMAAETKGBLDQXGRTJOEHRIAPXACPFTVGIXUJFZXUCX9EHUESMGQN9EHXEQTSKJHWDIR9OJYP9USDPWECONYRTFZREIZHOBAOXK9FCEOWCLUNKEWKE9JPQGDZ9PWAVQUMNBLVMESODMGJAIVNVJSFTQFL9RTTCJAFIMIGXASIREOXLNVEHMHPQZIKIPRQWFGYLQHVPMBNIWTWINSKW9WIWVDKHAIHNMBOCETYLNTJMA9XMEVQBPUFPKXJHXHPQCFKF9UYQQFKBBPPZMNAKPMMHPLBPDAOACLZ9HKVFGGMQHHHQLWYWYYGNXPEITKTVNURENFBAOBXITZDYCUSASIYEVJBYDLBIMUF9HILXKYH9IDYOFEQMBHJJBFDTNPDXSNSXCPUFGRIOXNYOSKHBILRWEFWZELL9GLNQOMPLMAPTOIJXSQXNPIW9XLMYEYVTNM9BVLVAIPZSYTCHHXGBQXHCBOQAUHZXKDWUREOOGKK9S9ZTKHGIQWHZOOFCGXBBCSYPGOGNRJLGVNWAGJZWKKLTHCJG9FJVRXMHQARRAHGUTITDDIMTIZAYARKJMQFCEAAOTHSHXDQKSNGMN99YGWRNLNMJXXFIQD9THOIHINYIEJMWRCZTAHJC9QIAKDIHIELNIMDKHFFWVCAHGMITJYNZ9XZSLFCGFFEQLONULNTQAJLOJTWO9BJQEBGTY9OCJBXKXNDEJWCDRYCNFDKYODHPAHQBGDXHMLVETVNRLRIJDHKAHZBAOFGMQFSTHPHBXKRAJFVIUDCKGNCDD9XTFDVNW9RLRNN9QRRUGOTMRRSVISCWE9ALTXCOCYHIQGXLGDB9RGICVSTUHJFWMWQCUICLJZCACGYCUHMGTGEJGAACGEXKJNJWKUGXRNBTEKIYUNXZZHXASCBPRDJAVXWESHU9DW9UVPJLWBKUXPDAIQ9JQPAHPMGVRUY9RLAMRTOKDVVUAZAPMNBSHRNNYDGC9BKAKKBPGHFDOHXCFWNSH9FZUMQHXMIUYKQLKHAYXPNEDYDUXTZXUKTBRJGBSZFMCNRZIQQLOLPRZPZBCX9EZBRUFGHGHBLYBLYYWZACGWGYRGV9IGZLTXOIMSCOTBNIGUXMOPVOFKIEUZASTZAHKXLYECJFLVZCORRFYDNVCYSKFCREQXXMDEHPSQFDERBICWFMOJS9PPSQYTVEXYSYGHWIWITZHRBZLHJWUYWQCAPLSBYJTJGCUXQPITAUJX9WEUVJDNUNKSDLHWDWKDQARSRKSLGLUCDNCERMKOJXCRXWCCYIAQZVGJLYTYQNGUDYYMXXL9XDBLEWPRMAY9DMMUHYUPMNBRRXJDIFDWEFJBRPYMPDPIPGXGXBMZ9JHAOISUMCNGUNCCPWKFJNBR9ZATRMDTOFDKMBQEZSCDSBNNEIUUCDHPHFBOBXLNGPOVZCATQRKVYSQHSHIVFZTW9BHPTPXUJGNNUBHWLZF9TBA9JONTWZRWHGHFIQGHAKSWBAHB99"),
                Tag       = new Tag("ASDF"),
                Timestamp = Timestamp.UnixSecondsTimestamp
            });

            expectedPayload.Finalize();
            expectedPayload.Sign();

            var seed = new Seed("JETCPWLCYRM9XYQMMZIFZLDBZZEWRMRVGWGGNCUH9LFNEHKEMLXAVEOFFVOATCNKVKELNQFAGOVUNWEJI");

            var channelFactory = new MamChannelFactory(CurlMamFactory.Default, CurlMerkleTreeFactory.Default, new InMemoryIotaRepository());
            var channelKey     = new TryteString("NXRZEZIKWGKIYDPVBRKWLYTWLUVSDLDCHVVSVIWDCIUZRAKPJUIABQDZBV9EGTJWUFTIGAUT9STIENCBC");
            var channel        = channelFactory.Create(Mode.Restricted, seed, SecurityLevel.Medium, channelKey);

            var message = channel.CreateMessage(new TryteString("IREALLYWANTTHISTOWORKINCSHARPASWELLPLEASEMAKEITHAPPEN"));

            Assert.AreEqual("RRPXQHDJY9BKXC9NGHDCSHRIDYORSUUEPFHXPQVDGSQTVYPCGVIZRWQINOUYFDUXTHFTKHLBOLYLHMKE9", message.Root.Value);
            Assert.AreEqual("BAVSMNXFTVBBEPXVROQYWBFHAELANDS9UFLDEOERJGKMXOGTL9UBEJF9WUDNGKUEDFZYAAFACRRRACDHV", message.Address.Value);
            Assert.AreEqual("OLHRFQPHPPQWTVSZNIZEKFOB9JPWKWQQPUCNLFAVEYCL9QVXRWFTDT9KPIHERRULOOBUKTJZJWKENTPLO", message.NextRoot.Value);

            Assert.AreEqual("OLHRFQPHPPQWTVSZNIZEKFOB9JPWKWQQPUCNLFAVEYCL9QVXRWFTDT9KPIHERRULOOBUKTJZJWKENTPLO", channel.NextRoot.Value);

            for (var i = 0; i < expectedPayload.Transactions.Count; i++)
            {
                Assert.AreEqual(expectedPayload.Transactions[i].Fragment.Value, message.Payload.Transactions[i].Fragment.Value);
            }
        }
        public void TestConversionFromTrytes()
        {
            var trytes = new TryteString("RBTC9D9DCDEAUCFDCDADEAMBHAFA");
            var output = trytes.ToAsciiString();

            Assert.AreEqual("Hello from C#!", output);
        }
示例#24
0
        private RestRequest CreateRequest(TryteString branchTransaction, TryteString trunkTransaction, IEnumerable <Transaction> transactions, int minWeightMagnitude)
        {
            var request = new RestRequest(Method.POST)
            {
                RequestFormat = DataFormat.Json
            };

            request.AddHeader("X-IOTA-API-Version", "1");

            if (!string.IsNullOrEmpty(this.ApiKey))
            {
                request.AddHeader("Authorization", $"powsrv-token {this.ApiKey}");
            }

            request.AddJsonBody(
                new Dictionary <string, object>
            {
                { "command", CommandType.AttachToTangle },
                { "trunkTransaction", trunkTransaction.Value },
                { "branchTransaction", branchTransaction.Value },
                { "minWeightMagnitude", minWeightMagnitude },
                { "trytes", transactions.Select(transaction => transaction.ToTrytes().Value).Reverse().ToList() }
            });

            return(request);
        }
示例#25
0
 public static string ComputeHash(string rawData)
 {
     using (var hashAlgorithm = SHA256.Create()) {
         var bytes = hashAlgorithm.ComputeHash(Encoding.UTF8.GetBytes(rawData));
         return(TryteString.FromBytes(bytes).Value);
     }
 }
示例#26
0
        /// <summary>
        /// The main.
        /// </summary>
        /// <param name="args">
        /// The args.
        /// </param>
        private static void Main(string[] args)
        {
            var repository = new RestIotaRepository(new RestClient("https://field.deviota.com:443"), new PoWSrvService());

            var bundle = new Bundle();

            bundle.AddTransfer(new Transfer
            {
                Address   = new Address(Hash.Empty.Value),
                Tag       = new Tag("MYCSHARPPI"),
                Timestamp = Timestamp.UnixSecondsTimestamp,
                Message   = TryteString.FromUtf8String("Hello from PiDiver #1!")
            });

            bundle.AddTransfer(new Transfer
            {
                Address   = new Address(Hash.Empty.Value),
                Tag       = new Tag("MYCSHARPPI"),
                Timestamp = Timestamp.UnixSecondsTimestamp,
                Message   = TryteString.FromUtf8String("Hello from PiDiver #2!")
            });

            bundle.Finalize();
            bundle.Sign();

            repository.SendTrytes(bundle.Transactions);


            Console.WriteLine("Done");
            Console.ReadKey();
        }
示例#27
0
        public static TryteString TryteStringIncrement(this TryteString tryteString)
        {
            // e.g. for "AAAAA" 10.596.375 possibilities
            var counter = 0;

            foreach (var character in tryteString.Value)
            {
                if (character == '9' || character == 'Z')
                {
                    counter++;
                }
                else
                {
                    // increments one letter
                    // ZAC - ZBC
                    var strBuilder = new StringBuilder(tryteString.Value)
                    {
                        [counter] = (char)(Convert.ToUInt16(character) + 1)
                    };
                    if (counter != 0)
                    {
                        // ABC
                        strBuilder[counter - 1] = 'A';
                    }

                    return(new TryteString(strBuilder.ToString()));
                }
            }

            return(tryteString);
        }
示例#28
0
        public void TestChunksAreSlicedCorrectly()
        {
            var tryteString = new TryteString("IAMGROOTU");
            var chunks      = tryteString.GetChunks(2);

            Assert.AreEqual(5, chunks.Count);
        }
示例#29
0
        public MamChannel Create(
            Mode mode,
            Seed seed,
            int securityLevel = SecurityLevel.Medium,
            string channelKey = null,
            bool keyIsTrytes  = false,
            Hash nextRoot     = null,
            int index         = 0,
            int count         = 1,
            int nextCount     = 1,
            int start         = 0)
        {
            var channel = new MamChannel(this.MamFactory, this.TreeFactory, this.Repository);

            channel.Init(
                mode,
                seed,
                securityLevel,
                channelKey != null ? keyIsTrytes ? new TryteString(channelKey) : TryteString.FromAsciiString(channelKey) : Hash.Empty,
                nextRoot,
                index,
                count,
                nextCount,
                start);

            return(channel);
        }
示例#30
0
        /// <summary>
        /// The main.
        /// </summary>
        /// <param name="args">
        /// The args.
        /// </param>
        private static void Main(string[] args)
        {
            var repository = new RestIotaRepository(
                new FallbackIotaClient(
                    new List <string>
            {
                "https://invalid.node.com:443",
                "https://peanut.iotasalad.org:14265",
                "http://node04.iotatoken.nl:14265",
                "http://node05.iotatoken.nl:16265",
                "https://nodes.thetangle.org:443",
                "http://iota1.heidger.eu:14265",
                "https://nodes.iota.cafe:443",
                "https://potato.iotasalad.org:14265",
                "https://durian.iotasalad.org:14265",
                "https://turnip.iotasalad.org:14265",
                "https://nodes.iota.fm:443",
                "https://tuna.iotasalad.org:14265",
                "https://iotanode2.jlld.at:443",
                "https://node.iota.moe:443",
                "https://wallet1.iota.town:443",
                "https://wallet2.iota.town:443",
                "http://node03.iotatoken.nl:15265",
                "https://node.iota-tangle.io:14265",
                "https://pow4.iota.community:443",
                "https://dyn.tangle-nodes.com:443",
                "https://pow5.iota.community:443",
            },
                    5000),
                new PoWSrvService());

            var bundle = new Bundle();

            bundle.AddTransfer(
                new Transfer
            {
                Address   = new Address(Hash.Empty.Value),
                Tag       = new Tag("MYCSHARPPI"),
                Timestamp = Timestamp.UnixSecondsTimestamp,
                Message   = TryteString.FromUtf8String("Hello from PiDiver #1!")
            });

            bundle.AddTransfer(
                new Transfer
            {
                Address   = new Address(Hash.Empty.Value),
                Tag       = new Tag("MYCSHARPPI"),
                Timestamp = Timestamp.UnixSecondsTimestamp,
                Message   = TryteString.FromUtf8String("Hello from PiDiver #2!")
            });

            bundle.Finalize();
            bundle.Sign();

            repository.SendTrytes(bundle.Transactions, 1);

            Console.WriteLine("Done");
            Console.ReadKey();
        }