示例#1
0
        /// <inheritdoc />
        public MaskedAuthenticatedMessage Create(
            MerkleTree tree,
            int index,
            TryteString message,
            Hash nextRoot,
            TryteString channelKey,
            Entity.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
            });
        }
示例#2
0
        /// <summary>
        /// The get message address.
        /// </summary>
        /// <param name="rootHash">
        /// The root Hash.
        /// </param>
        /// <param name="mode">
        /// The mode.
        /// </param>
        /// <returns>
        /// The <see cref="Address"/>.
        /// </returns>
        private Address GetMessageAddress(TryteString rootHash, Entity.Mode mode)
        {
            if (mode == Entity.Mode.Public)
            {
                return(new Address(rootHash.Value));
            }

            var addressHash = this.Mask.Hash(rootHash);

            return(new Address(addressHash.Value));
        }