Пример #1
0
        /// <summary>
        /// </summary>
        /// <param name="payload"></param>
        /// <param name="sideKey"></param>
        /// <param name="root"></param>
        /// <returns>(message,nextRoot)</returns>
        public Tuple <string, string> DecodeMessage(string payload, string sideKey, string root)
        {
            if (string.IsNullOrEmpty(sideKey))
            {
                sideKey = "999999999999999999999999999999999999999999999999999999999999999999999999999999999";
            }

            var payloadTrits = Converter.ToTrits(payload);
            var sideKeyTrits = Converter.ToTrits(sideKey);
            var rootTrits    = Converter.ToTrits(root);

            ICurl curl = new Curl(SpongeFactory.Mode.CURLP27);

            // parse
            var result   = Pascal.Decode(payloadTrits);
            var index    = (int)result.Item1;
            var indexEnd = result.Item2;

            var tempTrits = new sbyte[payloadTrits.Length - indexEnd];

            Array.Copy(payloadTrits, indexEnd, tempTrits, 0, tempTrits.Length);

            result = Pascal.Decode(tempTrits);
            var messageLength    = (int)result.Item1;
            var messageLengthEnd = result.Item2;

            var nextRootStart = indexEnd + messageLengthEnd;
            var messageStart  = nextRootStart + Constants.HashLength;
            var messageEnd    = messageStart + messageLength;

            curl.Absorb(sideKeyTrits);
            curl.Absorb(rootTrits);

            if (messageLength > payloadTrits.Length)
            {
                throw new ArgumentOutOfRangeException();
            }

            curl.Absorb(payloadTrits, 0, nextRootStart);

            MaskHelper.UnMaskSlice(payloadTrits, nextRootStart, messageStart - nextRootStart, curl);
            MaskHelper.UnMaskSlice(payloadTrits, messageStart, messageEnd - messageStart, curl);

            var pos = messageEnd;

            MaskHelper.UnMaskSlice(payloadTrits, pos, Constants.MessageNonceLength, curl);
            pos += Constants.HashLength / 3;

            var hmac = new sbyte[Constants.HashLength];

            Array.Copy(curl.Rate, hmac, Constants.HashLength);

            var security = HashHelper.CheckSumSecurity(hmac);

            MaskHelper.UnMaskSlice(payloadTrits, pos, payloadTrits.Length - pos, curl);

            if (security == 0)
            {
                // InvalidHash
                curl.Reset();
                throw new ApplicationException();
            }


            var sigEnd = pos + security * Constants.KeyLength;

            HashHelper.DigestBundleSignature(hmac, payloadTrits, pos, sigEnd - pos, curl);

            Array.Copy(curl.Rate, hmac, Constants.HashLength);
            curl.Reset();

            pos       = sigEnd;
            tempTrits = new sbyte[payloadTrits.Length - pos];
            Array.Copy(payloadTrits, pos, tempTrits, 0, tempTrits.Length);
            result = Pascal.Decode(tempTrits);

            curl.Absorb(hmac);
            if (result.Item1 != 0)
            {
                // get address lite
                Array.Copy(curl.Rate, hmac, Constants.HashLength);
                pos += result.Item2;
                var sibEnd = pos + (int)result.Item1;

                var siblings = new sbyte[sibEnd - pos];
                Array.Copy(payloadTrits, pos, siblings, 0, siblings.Length);

                curl.Reset();
                MerkleTree.Root(hmac, siblings, index, curl);
            }

            if (!curl.Rate.SequenceEqual(rootTrits))
            {
                // InvalidSignature
                curl.Reset();
                throw new ApplicationException();
            }

            var message  = Converter.ToTrytes(payloadTrits, messageStart, messageLength);
            var nextRoot = Converter.ToTrytes(payloadTrits, nextRootStart, Constants.HashLength);

            return(new Tuple <string, string>(message, nextRoot));
        }
Пример #2
0
        private sbyte[] CreateMaskedPayload(
            sbyte[] seedTrits, sbyte[] messageTrits,
            sbyte[] keyTrits, sbyte[] rootTrits,
            sbyte[] siblingsTrits, sbyte[] nextRootTrits,
            int start, int index, int security)
        {
            ICurl curl         = new Curl(SpongeFactory.Mode.CURLP27);
            ICurl encrCurl     = new Curl(SpongeFactory.Mode.CURLP27);
            var   hammingNonce = new HammingNonce(SpongeFactory.Mode.CURLP27);

            var minLength     = GetPayloadMinLength(messageTrits.Length, siblingsTrits.Length, index, security);
            var payloadLength = (int)TritsHelper.RoundThird(minLength);
            var payload       = new sbyte[payloadLength];

            // Creates a signed, encrypted payload from a message

            // generate the key and the get the merkle tree hashes
            var messageLength = messageTrits.Length;

            var indexP   = Pascal.EncodedLength(index);
            var messageP = Pascal.EncodedLength(messageLength);

            var siblingsLength       = siblingsTrits.Length;
            var siblingsCount        = siblingsTrits.Length / Constants.HashLength;
            var siblingsPascalLength = Pascal.EncodedLength(siblingsCount);
            var signatureLength      = security * Constants.KeyLength;

            var nextRootStart     = indexP + messageP;
            var nextEnd           = nextRootStart + nextRootTrits.Length;
            var messageEnd        = nextRootStart + Constants.HashLength + messageLength;
            var nonceEnd          = messageEnd + Constants.MessageNonceLength;
            var signatureEnd      = nonceEnd + signatureLength;
            var siblingsPascalEnd = signatureEnd + siblingsPascalLength;
            var siblingsEnd       = siblingsPascalEnd + siblingsLength;

            encrCurl.Absorb(keyTrits);
            encrCurl.Absorb(rootTrits);

            var trits = new sbyte[indexP];

            Pascal.Encode(index, trits);
            Array.Copy(trits, 0, payload, 0, indexP);

            trits = new sbyte[messageP];
            Pascal.Encode(messageLength, trits);
            Array.Copy(trits, 0, payload, indexP, messageP);

            encrCurl.Absorb(payload, 0, nextRootStart);
            Array.Copy(nextRootTrits, 0, payload, nextRootStart, nextRootTrits.Length);
            Array.Copy(messageTrits, 0, payload, nextEnd, messageTrits.Length);
            MaskHelper.MaskSlice(payload, nextRootStart, messageEnd - nextRootStart, encrCurl);

            Array.Copy(encrCurl.State, curl.State, encrCurl.State.Length);


            hammingNonce.Search(security, 0, Constants.HashLength / 3, curl);
            Array.Copy(curl.State, 0, payload, messageEnd, Constants.MessageNonceLength);
            MaskHelper.MaskSlice(payload, messageEnd, nonceEnd - messageEnd, encrCurl);

            curl.Reset();
            var subseed = HashHelper.Subseed(seedTrits, start + index, curl);

            Array.Copy(subseed, 0, payload, nonceEnd, subseed.Length);

            curl.Reset();
            HashHelper.Key(payload, nonceEnd, signatureEnd - nonceEnd, security, curl);

            curl.Reset();
            HashHelper.Signature(encrCurl.Rate, payload, nonceEnd, signatureEnd - nonceEnd, curl);

            curl.Reset();

            trits = new sbyte[siblingsPascalLength];
            Pascal.Encode(siblingsCount, trits);
            Array.Copy(trits, 0, payload, signatureEnd, siblingsPascalLength);
            Array.Copy(siblingsTrits, 0, payload, siblingsPascalEnd, siblingsLength);

            MaskHelper.MaskSlice(payload, nonceEnd, siblingsEnd - nonceEnd, encrCurl);
            encrCurl.Reset();

            return(payload);
        }