예제 #1
0
        public void TestValueEncoding()
        {
            var encoded  = Pascal.Encode(0);
            var expected = new[] { 1, 0, 0, -1 };

            for (var i = 0; i < expected.Length; i++)
            {
                Assert.AreEqual(expected[i], encoded[i]);
            }

            encoded  = Pascal.Encode(9);
            expected = new[] { 0, 0, 1, 0 };

            for (var i = 0; i < expected.Length; i++)
            {
                Assert.AreEqual(expected[i], encoded[i]);
            }

            encoded  = Pascal.Encode(1000);
            expected = new[] { -1, 0, 0, -1, 0, -1, 1, 0, 0, 0, 1, 0 };

            for (var i = 0; i < expected.Length; i++)
            {
                Assert.AreEqual(expected[i], encoded[i]);
            }
        }
예제 #2
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
            });
        }
예제 #3
0
 private int GetPayloadMinLength(int messageTritsLength, int siblingsTritsLength, int index, int security)
 {
     return
         (Pascal.EncodedLength(index) +
          Pascal.EncodedLength(Constants.HashLength + messageTritsLength) + Constants.HashLength +
          messageTritsLength + Constants.MessageNonceLength + security * Constants.KeyLength +
          Pascal.EncodedLength(siblingsTritsLength / Constants.HashLength) + siblingsTritsLength);
 }
예제 #4
0
        private void Pascal_SelectionChanged(object sender, EventArgs e)
        {
            Point pt = Pascal.GetPositionFromCharIndex(Pascal.SelectionStart);

            if (pt.X == 1)
            {
                AddLineNumbers(Pascal, LinearNumberPascal);
            }
        }
예제 #5
0
 public AtmosphereState(string name, int update, Guid self, ResourceComposition[] composition, Pascal pressure, Kelvin temperature)
 {
     this.name        = name;
     this.update      = update;
     this.self        = self;
     this.pressure    = pressure;
     this.temperature = temperature;
     this.composition = composition;
 }
예제 #6
0
        private bool GenerateDiscreteRandom()
        {
            My_Random_Discrete_Base rand = null;

            if (RadiobuttonDiscretteBernoulli.IsChecked == true)
            {
                double p = randomParametersDiscretteRandom.TextBoxParameterp.GetDoubleValue();
                rand = new Bernoulli(p);
            }
            if (RadiobuttonDiscretteBinomial.IsChecked == true)
            {
                long   n = randomParametersDiscretteRandom.TextBoxParametern.GetIntegerValue();
                double p = randomParametersDiscretteRandom.TextBoxParameterp.GetDoubleValue();
                rand = new Binomial(n, p);
            }
            if (RadiobuttonDiscretteEquilikely.IsChecked == true)
            {
                long a = randomParametersDiscretteRandom.TextBoxParametera.GetIntegerValue();
                long b = randomParametersDiscretteRandom.TextBoxParameterb.GetIntegerValue();
                rand = new Equilikely(a, b);
            }
            if (RadiobuttonDiscretteGeometric.IsChecked == true)
            {
                double p = randomParametersDiscretteRandom.TextBoxParameterp.GetDoubleValue();
                rand = new Geometric(p);
            }
            if (RadiobuttonDiscrettePascal.IsChecked == true)
            {
                long   n = randomParametersDiscretteRandom.TextBoxParametern.GetIntegerValue();
                double p = randomParametersDiscretteRandom.TextBoxParameterp.GetDoubleValue();
                rand = new Pascal(n, p);
            }
            if (RadiobuttonDiscrettePoisson.IsChecked == true)
            {
                double m = randomParametersDiscretteRandom.TextBoxParameterm.GetDoubleValue();
                rand = new Poisson(m);
            }
            if (RadiobuttonDiscretteSimple.IsChecked == true)
            {
                int d = randomParametersDiscretteRandom.TextBoxParameterRange.GetIntegerValue();
                rand = new SimpleDiscrete(d);
            }
            rand.SizeVector = genSettings.Size;

            if (timeUnitUserControlClock.TimeInterval.GetTimeUnitInFS() == 0)
            {
                MessageBox.Show("Time must be non zero", "Error!", MessageBoxButton.OK);
                return(false);
            }

            rand.TimeStep = timeUnitUserControlDiscretteRandom.TimeInterval;

            generator = rand;
            return(true);
        }
예제 #7
0
 public PressurisationState(string name, int update, Guid self, Guid atmospherics, IInventory inventory)
 {
     this.name         = name;
     this.update       = update;
     this.self         = self;
     this.inventory    = inventory;
     this.atmospherics = atmospherics;
     pressure          = 0;
     resourcesDesired  = null;
     molesOfGas        = 0;
     molesOfGasDesired = 0;
 }
예제 #8
0
 public PressurisationState(string name, int update, Guid self, Guid atmospherics, IInventory inventory, Pascal pressure, ResourceStack[] resourcesDesired, Mole molesOfGas, Mole molesOfGasDesired)
 {
     this.name              = name;
     this.update            = update;
     this.self              = self;
     this.atmospherics      = atmospherics;
     this.inventory         = inventory;
     this.pressure          = pressure;
     this.resourcesDesired  = resourcesDesired;
     this.molesOfGas        = molesOfGas;
     this.molesOfGasDesired = molesOfGasDesired;
 }
예제 #9
0
 public PressurisationState(object[] parameters)
 {
     name              = (string)parameters[1];
     update            = (int)parameters[2];
     self              = (Guid)parameters[3];
     atmospherics      = (Guid)parameters[4];
     inventory         = (IInventory)parameters[5];
     pressure          = (Pascal)parameters[6];
     resourcesDesired  = (ResourceStack[])parameters[7];
     molesOfGas        = (Mole)parameters[8];
     molesOfGasDesired = (Mole)parameters[9];
 }
예제 #10
0
        private void TestEncoding(long input)
        {
            int length = Pascal.EncodedLength(input);

            sbyte[] trits = new sbyte[length];

            Pascal.Encode(input, trits);

            var result = Pascal.Decode(trits);

            Assert.AreEqual(input, result.Item1);
            Assert.AreEqual(trits.Length, result.Item2);
        }
예제 #11
0
        public void Should_Convert_To_CamelCase_Json_With_Default_Client_Configuration_Serialization_Settings()
        {
            var data = new Pascal
            {
                SomeProperty    = "SOME",
                SomeIntProperty = 12345,
                HasPascalCase   = true
            };
            const string expectedJson = "{\"someProperty\":\"SOME\",\"someIntProperty\":12345,\"hasPascalCase\":true}";
            var          actualJson   = JsonConvert.SerializeObject(data, new ClientConfiguration().SerializationSettings);

            Assert.AreEqual(expectedJson, actualJson);
        }
예제 #12
0
        public IState Update(StateHandler handler)
        {
            PressurisationState state     = (PressurisationState)handler.State;
            AtmosphereState     atmoState = state.atmospherics.State <AtmosphereState>();

            ResourceStack[]       resources   = state.inventory.Resources();
            ResourceComposition[] composition = atmoState.composition;
            Mole   molesOfGas        = MolesOfGas(resources);
            Pascal pressure          = Pressure(molesOfGas, atmoState.temperature, state.inventory.MaxVolume());
            Mole   molesOfGasDesired = MolesOfGasDesired(molesOfGas, pressure, atmoState.temperature, state.inventory.MaxVolume());

            ResourceStack[] resourcesDesired = ResourcesDesired(resources, composition, molesOfGasDesired);
            return(new PressurisationState(Literals.States.Pressurisation, sequence, state.self, state.atmospherics, state.inventory, pressure, resourcesDesired, molesOfGas, molesOfGasDesired));
        }
예제 #13
0
        public void Should_Convert_To_PascalCase_Json_With_Altered_Serialization_Settings()
        {
            var data = new Pascal
            {
                SomeProperty    = "SOME",
                SomeIntProperty = 12345,
                HasPascalCase   = true
            };
            const string expectedJson         = "{\"SomeProperty\":\"SOME\",\"SomeIntProperty\":12345,\"HasPascalCase\":true}";
            var          serializationSetting = new ClientConfiguration().SerializationSettings;

            serializationSetting.ContractResolver = new DefaultContractResolver();
            var actualJson = JsonConvert.SerializeObject(data, serializationSetting);

            Assert.AreEqual(expectedJson, actualJson);
        }
        public void Should_Convert_To_CamelCase_Json_With_Default_Serialization_Settings()
        {
            var transcoder = new DefaultTranscoder(new ManualByteConverter());
            var data       = new Pascal
            {
                SomeProperty    = "SOME",
                SomeIntProperty = 12345,
                HasPascalCase   = true
            };
            var expectedJsonBytes = Encoding.UTF8.GetBytes("{\"someProperty\":\"SOME\",\"someIntProperty\":12345,\"hasPascalCase\":true}");
            var actualJsonBytes   = transcoder.SerializeAsJson(data);
            var actualJsonEncoded = transcoder.Encode(data, new Flags());

            Assert.AreEqual(expectedJsonBytes, actualJsonBytes);
            Assert.AreEqual(expectedJsonBytes, actualJsonEncoded);
        }
예제 #15
0
 public VolatileModuleState(VolatileModule self)
 {
     updateSequence             = self.updateSequence;
     volume                     = self.volume;
     energyProduction           = self.energyProductionTotal;
     self.energyProductionTotal = 0;
     energyTransferRate         = self.energyTransferRate;
     structuralIntegrity        = self.structuralIntegrity;
     structuralIntegrityMax     = self.structuralIntegrityMax;
     pressurisation             = self.pressurisation;
     pressurisationDesired      = self.pressurisationDesired;
     occupants                  = self.occupants;
     occupantsMax               = self.occupantsMax;
     // TODO IInventory SaveState()
     // if (self.pressurisation > 0) { self.pressurisationGasses.SaveState(); }
     // self.Inventory.SaveState();
     // self.CostOfOperation.SaveState();
     timestamp = DateTime.Now.Millisecond;
 }
예제 #16
0
        public void TestValueDecoding()
        {
            var expected      = new Tuple <int, int>(0, 4);
            var valueToDecode = new[] { 1, 0, 0, -1 };
            var result        = Pascal.Decode(valueToDecode);

            Assert.AreEqual(expected.Item1, result.Item1);
            Assert.AreEqual(expected.Item2, result.Item2);

            expected      = new Tuple <int, int>(1000, 12);
            valueToDecode = new[] { -1, 0, 0, -1, 0, -1, 1, 0, 0, 0, 1, 0 };
            result        = Pascal.Decode(valueToDecode);

            Assert.AreEqual(expected.Item1, result.Item1);
            Assert.AreEqual(expected.Item2, result.Item2);

            valueToDecode = new[] { -1, 0, 0, -1, 0, -1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, -1 };
            result        = Pascal.Decode(valueToDecode);

            Assert.AreEqual(expected.Item1, result.Item1);
            Assert.AreEqual(expected.Item2, result.Item2);
        }
예제 #17
0
        public int[] Search(int[] trits, int security, int length, int offset)
        {
            var ulongTrits = this.PrepareTrits(trits, offset);
            var curl       = new NonceCurl(ulongTrits.Low, ulongTrits.High, this.Rounds);
            var size       = Math.Min(length, AbstractCurl.HashLength) - offset;

            var index = 0;

            while (index == 0)
            {
                var incrementResult = curl.Increment(offset + size * 2 / 3, offset + size);
                size = Math.Min(Pascal.RoundThird(offset + size * 2 / 3 + incrementResult), AbstractCurl.HashLength) - offset;

                var curlCopy = curl.Clone();
                curlCopy.Transform();

                index = Check(security, curlCopy.Low.Take(AbstractCurl.HashLength).ToArray(), curlCopy.High.Take(AbstractCurl.HashLength).ToArray());
            }

            var result = new TrinaryDemultiplexer(new UlongTritTouple(curl.Low.Take(size).ToArray(), curl.High.Take(size).ToArray()));

            return(result.Get(index));
        }
예제 #18
0
        public void Should_Convert_To_PascalCase_Json_With_Altered_Serialization_Settings()
        {
            var transcoder = new DefaultTranscoder(
                new DefaultConverter(),
                new DefaultSerializer(
                    new JsonSerializerSettings(),
                    new JsonSerializerSettings
            {
                ContractResolver = new DefaultContractResolver()
            }));

            var data = new Pascal
            {
                SomeProperty    = "SOME",
                SomeIntProperty = 12345,
                HasPascalCase   = true
            };
            var expectedJsonBytes = Encoding.UTF8.GetBytes("{\"SomeProperty\":\"SOME\",\"SomeIntProperty\":12345,\"HasPascalCase\":true}");
            var actualJsonBytes   = transcoder.SerializeAsJson(data);
            var actualJsonEncoded = transcoder.Encode(data, TypeCode.Object, OperationCode.Get);

            Assert.AreEqual(expectedJsonBytes, actualJsonBytes);
            Assert.AreEqual(expectedJsonBytes, actualJsonEncoded);
        }
예제 #19
0
        /// <inheritdoc />
        public UnmaskedAuthenticatedMessage Unmask(Bundle payload, TryteString root, TryteString channelKey)
        {
            var payloadTrits = payload.Transactions.Select(t => t.Fragment).ToList().Merge().ToTrits();

            // Get data indices
            var indexData     = Pascal.Decode(payloadTrits);
            var index         = indexData.Item1;
            var messageData   = Pascal.Decode(payloadTrits.Skip(indexData.Item2).ToArray());
            var messageLength = messageData.Item1;
            var nextRootStart = indexData.Item2 + messageData.Item2;
            var messageStart  = nextRootStart + Constants.TritHashLength;
            var messageEnd    = messageStart + messageLength;

            // Absorb key, root, index and message trits
            this.Curl.Reset();
            this.Curl.Absorb(channelKey.ToTrits());
            this.Curl.Absorb(root.ToTrits());
            this.Curl.Absorb(payloadTrits.Take(nextRootStart).ToArray());

            // decrypt metadata and create hmac
            var nextRoot = this.Mask.Unmask(payloadTrits.Skip(nextRootStart).Take(Constants.TritHashLength).ToArray(), this.Curl);
            var message  = this.Mask.Unmask(payloadTrits.Skip(messageStart).Take(messageLength).ToArray(), this.Curl);
            var nonce    = this.Mask.Unmask(payloadTrits.Skip(messageEnd).Take(Constants.TritHashLength / 3).ToArray(), this.Curl);
            var hmac     = this.Curl.Rate(Constants.TritHashLength);

            // verify security level with hmac
            var securityLevel = this.SigningHelper.ChecksumSecurity(hmac);

            if (securityLevel == 0)
            {
                throw new ArgumentException("Given payload is invalid. (Security level can not be verified)");
            }

            // decrypt remaining payload
            var decryptedMetadata = this.Mask.Unmask(payloadTrits.Skip(messageEnd + nonce.Length).ToArray(), this.Curl);

            this.Curl.Reset();

            // get signature, derive digest and absorb it
            var signature = decryptedMetadata.Take(securityLevel * PrivateKey.FragmentLength).ToArray();

            this.Curl.Absorb(this.SigningHelper.DigestFromSignature(hmac, signature));

            // decode sibling information and recalculate root to verify payload
            var siblingsCountData = Pascal.Decode(decryptedMetadata.Skip(securityLevel * PrivateKey.FragmentLength).ToArray());
            var siblingsCount     = siblingsCountData.Item1;
            var recalculatedRoot  = siblingsCount != 0
                           ? this.RecalculateRootWithSiblings(decryptedMetadata, securityLevel, siblingsCountData.Item2, siblingsCount, index)
                           : new Hash(Converter.TritsToTrytes(this.Curl.Rate(Constants.TritHashLength)));

            if (recalculatedRoot.Value != root.Value)
            {
                throw new ArgumentException("Given payload is invalid. (Given root does not match payload root)");
            }

            return(new UnmaskedAuthenticatedMessage
            {
                NextRoot = new Hash(Converter.TritsToTrytes(nextRoot)),
                Message = new TryteString(Converter.TritsToTrytes(message)),
                Root = new Hash(root.Value)
            });
        }
예제 #20
0
 private void Pascal_MouseDown(object sender, MouseEventArgs e)
 {
     Pascal.Select();
     LinearNumberPascal.DeselectAll();
 }
예제 #21
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);
            var subtreeTrytes = subtree.ToTryteString();
            var subtreeTrits  = subtreeTrytes.ToTrits();

            var siblingsLength     = subtreeTrits.Length;
            var siblingsCount      = siblingsLength / Constants.TritHashLength;
            var siblingsCountTrits = Pascal.Encode(siblingsCount);
            var signatureLength    = subtree.Key.TrytesLength * Converter.Radix;

            var nextRootStart = indexTrits.Length + messageLengthTrits.Length;
            var nextRootEnd   = nextRootStart + nextRootTrits.Length;

            var messageEnd   = nextRootStart + nextRootTrits.Length + messageTrits.Length;
            var nonceEnd     = messageEnd + NonceLength;
            var signatureEnd = nonceEnd + signatureLength;

            var siblingsCountTritsEnd = signatureEnd + siblingsCountTrits.Length;

            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);

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

            payload.InsertRange(nextRootStart, nextRootTrits);
            payload.InsertRange(nextRootEnd, messageTrits);

            var encryptablePayloadPart = payload.Skip(nextRootStart).Take(nextRootTrits.Length + messageTrits.Length).ToArray();

            this.Mask.Mask(encryptablePayloadPart, this.Curl);

            for (var i = 0; i < encryptablePayloadPart.Length; i++)
            {
                payload[nextRootStart + i] = encryptablePayloadPart[i];
            }

            var nonceTrits = this.HammingNonceDiver.Search(this.Curl.Rate(this.Curl.State.Length), securityLevel, Constants.TritHashLength / 3, 0)
                             .ToArray();

            this.Mask.Mask(nonceTrits, this.Curl);
            payload.InsertRange(messageEnd, nonceTrits);

            var signature = this.SigningHelper.Signature(this.Curl.Rate(Constants.TritHashLength), subtree.Key.ToTrits());

            payload.InsertRange(nonceEnd, signature);
            payload.InsertRange(signatureEnd, siblingsCountTrits);
            payload.InsertRange(siblingsCountTritsEnd, subtreeTrits);

            var encryptableSignaturePart = payload.Skip(nonceEnd).ToArray();

            this.Mask.Mask(encryptableSignaturePart, this.Curl);

            for (var i = 0; i < encryptableSignaturePart.Length; i++)
            {
                payload[nonceEnd + i] = encryptableSignaturePart[i];
            }

            var nextThirdRound = payload.Count % Converter.Radix;

            if (nextThirdRound != 0)
            {
                payload.InsertRange(payload.Count, new int[Converter.Radix - nextThirdRound]);
            }

            this.Curl.Reset();

            var bundle = new Bundle();

            bundle.AddTransfer(
                new Transfer
            {
                Address   = this.GetMessageAddress(tree.Root.Hash, mode),
                Message   = new TryteString(Converter.TritsToTrytes(payload.ToArray())),
                Timestamp = Timestamp.UnixSecondsTimestamp
            });

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

            return(new MaskedAuthenticatedMessage
            {
                Payload = bundle,
                Root = tree.Root.Hash,
                Address = this.GetMessageAddress(tree.Root.Hash, mode),
                NextRoot = nextRoot
            });
        }
예제 #22
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);
        }
예제 #23
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));
        }
예제 #24
0
        /// <inheritdoc />
        public UnmaskedAuthenticatedMessage Unmask(Bundle payload, TryteString root, TryteString channelKey)
        {
            var payloadTrits = payload.Transactions.Select(t => t.Fragment).ToList().Merge().ToTrits();

            var indexData = Pascal.Decode(payloadTrits);
            var index     = indexData.Item1;

            var messageData   = Pascal.Decode(payloadTrits.Skip(indexData.Item2).ToArray());
            var messageLength = messageData.Item1;
            var nextRootStart = indexData.Item2 + messageData.Item2;
            var messageStart  = nextRootStart + Constants.TritHashLength;
            var messageEnd    = messageStart + messageLength;

            this.Curl.Reset();
            this.Curl.Absorb(channelKey.ToTrits());
            this.Curl.Absorb(root.ToTrits());
            this.Curl.Absorb(payloadTrits.Take(nextRootStart).ToArray());

            var nextRoot = this.Mask.Unmask(payloadTrits.Skip(nextRootStart).Take(Constants.TritHashLength).ToArray(), this.Curl);
            var message  = this.Mask.Unmask(payloadTrits.Skip(messageStart).Take(messageLength).ToArray(), this.Curl);
            var nonce    = this.Mask.Unmask(payloadTrits.Skip(messageEnd).Take(Constants.TritHashLength / 3).ToArray(), this.Curl);
            var hmac     = this.Curl.Rate(Constants.TritHashLength);

            var securityLevel = this.SigningHelper.ChecksumSecurity(hmac);

            if (securityLevel == 0)
            {
                throw new ArgumentException("Given payload is invalid. (Security level can not be verified)");
            }

            var decryptedMetadata = this.Mask.Unmask(payloadTrits.Skip(messageEnd + nonce.Length).ToArray(), this.Curl);
            var signature         = decryptedMetadata.Take(securityLevel * PrivateKey.FragmentLength).ToArray();

            var digest = this.SigningHelper.DigestFromSignature(hmac, signature);

            this.Curl.Reset();
            this.Curl.Absorb(digest);

            var siblingsCountData = Pascal.Decode(decryptedMetadata.Skip(securityLevel * PrivateKey.FragmentLength).ToArray());
            var siblingsCount     = siblingsCountData.Item1;

            Hash recalculatedRoot;

            if (siblingsCount != 0)
            {
                var siblings = decryptedMetadata.Skip((securityLevel * PrivateKey.FragmentLength) + siblingsCountData.Item2)
                               .Take(siblingsCount * Constants.TritHashLength).ToArray();

                recalculatedRoot = this.TreeFactory.RecalculateRoot(
                    siblings,
                    this.Curl.Rate(Constants.TritHashLength),
                    index);
            }
            else
            {
                recalculatedRoot = new Hash(Converter.TritsToTrytes(this.Curl.Rate(Constants.TritHashLength)));
            }

            if (recalculatedRoot.Value != root.Value)
            {
                throw new ArgumentException("Given payload is invalid. (Given root does not match payload root)");
            }

            return(new UnmaskedAuthenticatedMessage
            {
                NextRoot = new Hash(Converter.TritsToTrytes(nextRoot)),
                Message = new TryteString(Converter.TritsToTrytes(message)),
                Root = new Hash(root.Value)
            });
        }
예제 #25
0
 public ImageBlur(int blur)
 {
     this.Blur = blur;
     Pascal    = PascalRow(Blur * 2);
     Det       = Pascal.Sum();
 }