Пример #1
0
        public void ClientInitializationClientReinstantiation()
        {
            BouncyCastleServices clientServices = new BouncyCastleServices(KeyGeneration.GeneratePrivateKey());
            BouncyCastleServices serverServices = new BouncyCastleServices(KeyGeneration.GeneratePrivateKey());

            var client           = new MicroRatchetContext(clientServices, true);
            var clientInitPacket = client.InitiateInitialization();
            var cs             = client.SaveStateAsByteArray();
            var server         = new MicroRatchetContext(serverServices, false);
            var responsePacket = server.Receive(clientInitPacket).ToSendBack;
            var ss             = server.SaveStateAsByteArray();

            client = new MicroRatchetContext(clientServices, true, stateBytes: cs);
            var firstPacket = client.Receive(responsePacket).ToSendBack;

            cs     = client.SaveStateAsByteArray();
            server = new MicroRatchetContext(serverServices, false, stateBytes: ss);
            var firstResponse = server.Receive(firstPacket).ToSendBack;

            ss     = server.SaveStateAsByteArray();
            client = new MicroRatchetContext(clientServices, true, stateBytes: cs);
            var lastResult = client.Receive(firstResponse).ToSendBack;

            cs = client.SaveStateAsByteArray();

            Assert.Null(lastResult);
        }
Пример #2
0
        public static (MicroRatchetContext client, MicroRatchetContext server) CreateAndInitialize(int mtu = 80, int maximumBufferedPartialMessageSize = 50 * 1024)
        {
            var clientServices = new BouncyCastleServices(KeyGeneration.GeneratePrivateKey());
            var serverServices = new BouncyCastleServices(KeyGeneration.GeneratePrivateKey());

            var client = new MicroRatchetContext(clientServices, true);
            var server = new MicroRatchetContext(serverServices, false);

            var packet = client.InitiateInitialization();

            while (!client.IsInitialized || !server.IsInitialized)
            {
                packet = server.Receive(packet).ToSendBack;
                if (packet != null)
                {
                    packet = client.Receive(packet).ToSendBack;
                }
            }

            var cs = client.SaveStateAsByteArray();
            var ss = server.SaveStateAsByteArray();

            return(new MicroRatchetContext(clientServices, true, mtu, stateBytes: cs),
                   new MicroRatchetContext(serverServices, false, mtu, stateBytes: ss));
        }
Пример #3
0
        public void ClientInitialization2ProcessTest()
        {
            BouncyCastleServices clientServices = new BouncyCastleServices(KeyGeneration.GeneratePrivateKey());
            BouncyCastleServices serverServices = new BouncyCastleServices(KeyGeneration.GeneratePrivateKey());

            var client = new MicroRatchetContext(clientServices, true);
            var server = new MicroRatchetContext(serverServices, false);

            var         clientInitPacket = client.InitiateInitialization();
            var         responsePacket   = server.Receive(clientInitPacket).ToSendBack;
            var         cs          = client.SaveStateAsByteArray();
            var         ss          = server.SaveStateAsByteArray();
            ClientState clientState = ClientState.Load(cs, DefaultKexFactory.Instance);
            ServerState serverState = ServerState.Load(ss, DefaultKexFactory.Instance);
        }
Пример #4
0
        public void ClientInitialization1MessageTest()
        {
            BouncyCastleServices clientServices = new BouncyCastleServices(KeyGeneration.GeneratePrivateKey());

            var client = new MicroRatchetContext(clientServices, true);

            var         clientInitPacket = client.InitiateInitialization();
            var         sb          = client.SaveStateAsByteArray();
            ClientState clientState = ClientState.Load(sb, DefaultKexFactory.Instance);

            Assert.NotNull(clientState.LocalEcdhForInit);
            Assert.NotNull(clientState.InitializationNonce);

            Assert.Equal(MicroRatchetContext.InitializationNonceSize, clientState.InitializationNonce.Length);
        }
Пример #5
0
        public void ClientInitializationRetransmitThrowsTest()
        {
            // this test makes sure that during the initialization process
            // any retransmitted packet will cause an exception. However,
            // the initialization process will not be affected and a client
            // and server can still process non-repeated messages.

            BouncyCastleServices clientServices = new BouncyCastleServices(KeyGeneration.GeneratePrivateKey());
            BouncyCastleServices serverServices = new BouncyCastleServices(KeyGeneration.GeneratePrivateKey());

            var client = new MicroRatchetContext(clientServices, true);
            var server = new MicroRatchetContext(serverServices, false);

            var clientInitPacket = client.InitiateInitialization();
            var responsePacket   = server.Receive(clientInitPacket.ToArray()).ToSendBack;

            Assert.Throws <InvalidOperationException>(() => server.Receive(clientInitPacket.ToArray()));
            var firstPacket = client.Receive(responsePacket.ToArray()).ToSendBack;

            Assert.Throws <InvalidOperationException>(() => client.Receive(responsePacket.ToArray()));
            var firstResponse = server.Receive(firstPacket.ToArray()).ToSendBack;

            Assert.Throws <InvalidOperationException>(() => server.Receive(firstPacket.ToArray()));
            var lastResult = client.Receive(firstResponse.ToArray()).ToSendBack;

            Assert.Throws <InvalidOperationException>(() => client.Receive(firstResponse.ToArray()));
            var         cs          = client.SaveStateAsByteArray();
            var         ss          = server.SaveStateAsByteArray();
            ClientState clientState = ClientState.Load(cs, DefaultKexFactory.Instance);
            ServerState serverState = ServerState.Load(ss, DefaultKexFactory.Instance);

            var rng = new RandomNumberGenerator();

            byte[] message1 = rng.Generate(32);
            byte[] message2 = rng.Generate(32);
            var    m1       = client.Send(message1);
            var    p1       = server.Receive(m1).Payload;
            var    m2       = server.Send(message2);
            var    p2       = client.Receive(m2).Payload;

            Assert.Equal(message1, p1);
            Assert.Equal(message2, p2);
        }
Пример #6
0
        public void ServerCanSendLargeMessageAfterInitialization()
        {
            BouncyCastleServices clientServices = new BouncyCastleServices(KeyGeneration.GeneratePrivateKey());
            BouncyCastleServices serverServices = new BouncyCastleServices(KeyGeneration.GeneratePrivateKey());

            var client = new MicroRatchetContext(clientServices, true);
            var server = new MicroRatchetContext(serverServices, false);

            var clientInitPacket = client.InitiateInitialization();
            var responsePacket   = server.Receive(clientInitPacket).ToSendBack;
            var firstPacket      = client.Receive(responsePacket).ToSendBack;
            var firstResponse    = server.Receive(firstPacket).ToSendBack;
            var lastResult       = client.Receive(firstResponse).ToSendBack;
            var cs = client.SaveStateAsByteArray();
            var ss = server.SaveStateAsByteArray();

            byte[] payload = new byte[server.Configuration.MaximumMessageSize - MicroRatchetContext.MinimumOverhead];
            clientServices.RandomNumberGenerator.Generate(payload);
            byte[] message  = server.Send(payload);
            byte[] received = client.Receive(message).Payload;
            Assert.Equal(payload, received);
        }
Пример #7
0
        private static (MicroRatchetContext client, MicroRatchetContext server) CreateAndInitialize(int?mtu = null)
        {
            BouncyCastleServices clientServices = new BouncyCastleServices(KeyGeneration.GeneratePrivateKey());
            BouncyCastleServices serverServices = new BouncyCastleServices(KeyGeneration.GeneratePrivateKey());

            var client = new MicroRatchetContext(clientServices, true);
            var server = new MicroRatchetContext(serverServices, false);

            var packet = client.InitiateInitialization();

            while (packet != null && !client.IsInitialized || !server.IsInitialized)
            {
                packet = server.Receive(packet).ToSendBack;
                if (packet != null)
                {
                    packet = client.Receive(packet).ToSendBack;
                }
            }

            if (!client.IsInitialized || !server.IsInitialized)
            {
                throw new InvalidOperationException("Initialization failed");
            }

            using var msc = new MemoryStream();
            using var mss = new MemoryStream();
            client.SaveState(msc); msc.Position = 0;
            server.SaveState(mss); mss.Position = 0;

            return(
                new MicroRatchetContext(clientServices, new MicroRatchetConfiguration {
                IsClient = true, MaximumMessageSize = mtu ?? 80
            }, msc),
                new MicroRatchetContext(serverServices, new MicroRatchetConfiguration {
                IsClient = false, MaximumMessageSize = mtu ?? 80
            }, mss));
        }
Пример #8
0
        static void Main(string[] args)
        {
            int    messageCount     = 1000000;
            double clientDropChance = 0.0;
            double serverDropChance = 0.0;
            var    defaultServices  = new BouncyCastleServices(KeyGeneration.GeneratePrivateKey());

            Random r = new Random();
            RandomNumberGenerator rng = new RandomNumberGenerator();
            Stopwatch             sw  = new Stopwatch();

            Console.WriteLine("Generating data...");
            byte[] keys   = new byte[16 * 1000000];
            byte[] blocks = new byte[16 * 1000000];
            byte[] output = new byte[32 * 1000000];
            rng.Generate(keys);
            rng.Generate(blocks);

            Thread.Sleep(1000);
            {
                var poly = new Poly(defaultServices.AesFactory);
                poly.Init(new ArraySegment <byte>(keys, 0, 32), new ArraySegment <byte>(blocks, 0, 16), 16);
                poly.Init(new ArraySegment <byte>(keys, 1000, 32), new ArraySegment <byte>(blocks, 1000, 16), 16);
                Console.WriteLine("Doing Pol1305 MACs");
                sw.Reset();
                sw.Start();
                for (int i = 0; i < keys.Length; i += 32)
                {
                    poly.Process(blocks, i, 16);
                    poly.Process(blocks, i, 16);
                    poly.Process(blocks, i, 16);
                    poly.Process(blocks, i, 16);
                    poly.Compute(new ArraySegment <byte>(output, i, 16));
                }
                sw.Stop();
                Console.WriteLine($"Took {sw.Elapsed.TotalSeconds:F2}s ({(keys.Length / 32) / sw.Elapsed.TotalSeconds:F0}/s)");
            }
            Thread.Sleep(1000);
            {
                var sha = System.Security.Cryptography.SHA256.Create();
                sha.ComputeHash(blocks, 10000, 16);
                Console.WriteLine("Doing SHA256 hashes (dotnet)");
                sw.Reset();
                sw.Start();
                for (int i = 0; i < blocks.Length; i += 16)
                {
                    sha.ComputeHash(blocks, i, 16);
                }

                sw.Stop();
                Console.WriteLine($"Took {sw.Elapsed.TotalSeconds:F2}s ({(keys.Length / 16) / sw.Elapsed.TotalSeconds:F0}/s)");
            }
            Thread.Sleep(1000);
            {
                var sha = new Org.BouncyCastle.Crypto.Digests.Sha256Digest();
                sha.BlockUpdate(blocks, 10000, 16);
                sha.DoFinal(output, 10000);
                Console.WriteLine("Doing SHA256 hashes (bc)");
                sw.Reset();
                sw.Start();
                for (int i = 0; i < blocks.Length; i += 16)
                {
                    sha.BlockUpdate(blocks, i, 16);
                    sha.DoFinal(output, i * 2);
                }

                sw.Stop();
                Console.WriteLine($"Took {sw.Elapsed.TotalSeconds:F2}s ({(keys.Length / 16) / sw.Elapsed.TotalSeconds:F0}/s)");
            }

            Thread.Sleep(1000);
            {
                var aes = System.Security.Cryptography.Aes.Create();
                aes.Mode = System.Security.Cryptography.CipherMode.ECB;
                var key = new byte[16];
                Array.Copy(keys, 10000, key, 0, 16);
                aes.CreateEncryptor(key, null);
                Console.WriteLine("Calculating AES keys (dotnet)");
                sw.Reset();
                sw.Start();
                for (int i = 0; i < keys.Length; i += 16)
                {
                    Array.Copy(keys, i, key, 0, 16);
                    aes.CreateEncryptor(key, null);
                }

                sw.Stop();
                Console.WriteLine($"Took {sw.Elapsed.TotalSeconds:F2}s ({(keys.Length / 16) / sw.Elapsed.TotalSeconds:F0}/s)");
            }
            Thread.Sleep(1000);
            {
                var aes = System.Security.Cryptography.Aes.Create();
                aes.Mode = System.Security.Cryptography.CipherMode.ECB;
                var key = new byte[16];
                Array.Copy(keys, key, 16);
                var enc = aes.CreateEncryptor(key, null);
                enc.TransformBlock(blocks, 10000, 16, output, 10000);
                Console.WriteLine("Processing AES blocks (dotnet");
                sw.Reset();
                sw.Start();
                for (int i = 0; i < blocks.Length; i += 16)
                {
                    enc.TransformBlock(blocks, i, 16, output, i);
                }
                sw.Stop();
                Console.WriteLine($"Took {sw.Elapsed.TotalSeconds:F2}s ({(keys.Length / 16) / sw.Elapsed.TotalSeconds:F0}/s)");
            }
            Thread.Sleep(1000);
            {
                Org.BouncyCastle.Crypto.Engines.AesEngine aes = new Org.BouncyCastle.Crypto.Engines.AesEngine();
                aes.Init(true, new KeyParameter(keys, 10000, 16));
                aes.Init(true, new KeyParameter(keys, 20000, 16));
                Console.WriteLine("Calculating AES keys (bc)");
                sw.Reset();
                sw.Start();
                for (int i = 0; i < keys.Length; i += 16)
                {
                    aes.Init(true, new KeyParameter(keys, i, 16));
                }
                sw.Stop();
                Console.WriteLine($"Took {sw.Elapsed.TotalSeconds:F2}s ({(keys.Length / 16) / sw.Elapsed.TotalSeconds:F0}/s)");
            }
            Thread.Sleep(1000);
            {
                Org.BouncyCastle.Crypto.Engines.AesEngine aes = new Org.BouncyCastle.Crypto.Engines.AesEngine();
                aes.Init(true, new KeyParameter(keys, 12300, 16));
                aes.ProcessBlock(blocks, 10000, output, 10000);
                Console.WriteLine("Processing AES blocks (bc)");
                sw.Reset();
                sw.Start();
                for (int i = 0; i < blocks.Length; i += 16)
                {
                    aes.ProcessBlock(blocks, i, output, i);
                }
                sw.Stop();
                Console.WriteLine($"Took {sw.Elapsed.TotalSeconds:F2}s ({(keys.Length / 16) / sw.Elapsed.TotalSeconds:F0}/s)");
            }
            Thread.Sleep(1000);
            {
                var aes = new Org.BouncyCastle.Crypto.Engines.AesLightEngine();
                aes.Init(true, new KeyParameter(keys, 10000, 16));
                aes.Init(true, new KeyParameter(keys, 20000, 16));
                Console.WriteLine("Calculating AES keys (bc light)");
                sw.Reset();
                sw.Start();
                for (int i = 0; i < keys.Length; i += 16)
                {
                    aes.Init(true, new KeyParameter(keys, i, 16));
                }
                sw.Stop();
                Console.WriteLine($"Took {sw.Elapsed.TotalSeconds:F2}s ({(keys.Length / 16) / sw.Elapsed.TotalSeconds:F0}/s)");
            }
            Thread.Sleep(1000);
            {
                var aes = new Org.BouncyCastle.Crypto.Engines.AesLightEngine();
                aes.Init(true, new KeyParameter(keys, 12340, 16));
                aes.ProcessBlock(blocks, 10000, output, 10000);
                Console.WriteLine("Processing AES blocks (bc light)");
                sw.Reset();
                sw.Start();
                for (int i = 0; i < blocks.Length; i += 16)
                {
                    aes.ProcessBlock(blocks, i, output, i);
                }
                sw.Stop();
                Console.WriteLine($"Took {sw.Elapsed.TotalSeconds:F2}s ({(keys.Length / 16) / sw.Elapsed.TotalSeconds:F0}/s)");
            }

            Thread.Sleep(1000);
            {
                SymmetricRacthet sr = new SymmetricRacthet();
                var(client, server) = CreateAndInitialize();
                var kdf = new AesKdf(client.Services.AesFactory);
                sr.Initialize(rng.Generate(32));
                Console.WriteLine("Testing Symmetric Ratchet Speed");
                sr.RatchetForSending(kdf);
                sr.RatchetForSending(kdf);
                sr.RatchetForSending(kdf);
                sr.RatchetForSending(kdf);
                sw.Reset();
                sw.Start();
                int cnt = 1000000;
                for (int i = 0; i < cnt; i++)
                {
                    sr.RatchetForSending(kdf);
                }
                sw.Stop();
                Console.WriteLine($"Took {sw.Elapsed.TotalSeconds:F2}s ({cnt / sw.Elapsed.TotalSeconds:F0}/s)");
                Console.WriteLine($"It would take { (double)int.MaxValue / 2 / (cnt / sw.Elapsed.TotalSeconds) / 60:F0} minutes to do 2^32 ratchets");
            }

            Thread.Sleep(1000);
            {
                Console.WriteLine("Testing one way message send speed (small: 16 bytes)...");
                var(client, server) = CreateAndInitialize();
                var messagesToSend = Enumerable.Range(0, messageCount).Select(_ => rng.Generate(16)).ToArray();
                var messagesSent   = new List <byte[]>(messageCount);
                var m1             = client.Send(new byte[16]);
                var m2             = client.Send(new byte[16]);
                var m3             = client.Send(new byte[16]);
                sw.Reset();
                sw.Start();
                for (int i = 0; i < messageCount; i++)
                {
                    messagesSent.Add(client.Send(messagesToSend[i]));
                }
                sw.Stop();
                Console.WriteLine($"Took {sw.Elapsed.TotalSeconds:F2}s ({messageCount / sw.Elapsed.TotalSeconds:F0}/s)");
                Console.WriteLine($"Bandwidth: { messagesToSend.Sum(x => x.Length * 8) / sw.Elapsed.TotalSeconds / (1024 * 1024):F0} Mbps");


                Thread.Sleep(1000);
                Console.WriteLine("Testing one way message receive speed (small: 16 bytes)...");
                server.Receive(m1);
                server.Receive(m2);
                server.Receive(m3);
                sw.Reset();
                sw.Start();
                for (int i = 0; i < messageCount; i++)
                {
                    server.Receive(messagesSent[i]);
                }
                sw.Stop();
                Console.WriteLine($"Took {sw.Elapsed.TotalSeconds:F2}s ({messageCount / sw.Elapsed.TotalSeconds:F0}/s)");
                Console.WriteLine($"Bandwidth: { messagesToSend.Sum(x => x.Length * 8) / sw.Elapsed.TotalSeconds / (1024 * 1024):F0} Mbps");
            }

            Thread.Sleep(2000);
            {
                Console.WriteLine("Testing one way message send speed (large: 64 bytes)...");
                var(client, server) = CreateAndInitialize();
                var messagesToSend = Enumerable.Range(0, messageCount).Select(_ => rng.Generate(64)).ToArray();
                var messagesSent   = new List <byte[]>(messageCount);
                var m1             = client.Send(new byte[16]);
                var m2             = client.Send(new byte[16]);
                var m3             = client.Send(new byte[16]);
                sw.Reset();
                sw.Start();
                for (int i = 0; i < messageCount; i++)
                {
                    messagesSent.Add(client.Send(messagesToSend[i]));
                }
                sw.Stop();
                Console.WriteLine($"Took {sw.Elapsed.TotalSeconds:F2}s ({messageCount / sw.Elapsed.TotalSeconds:F0}/s)");
                Console.WriteLine($"Bandwidth: { messagesToSend.Sum(x => x.Length * 8) / sw.Elapsed.TotalSeconds / (1024 * 1024):F0} Mbps");


                Thread.Sleep(1000);
                Console.WriteLine("Testing one way message receive speed (large: 64 bytes)...");
                server.Receive(m1);
                server.Receive(m2);
                server.Receive(m3);
                sw.Reset();
                sw.Start();
                for (int i = 0; i < messageCount; i++)
                {
                    server.Receive(messagesSent[i]);
                }
                sw.Stop();
                Console.WriteLine($"Took {sw.Elapsed.TotalSeconds:F2}s ({messageCount / sw.Elapsed.TotalSeconds:F0}/s)");
                Console.WriteLine($"Bandwidth: { messagesToSend.Sum(x => x.Length * 8) / sw.Elapsed.TotalSeconds / (1024 * 1024):F0} Mbps");
            }

            messageCount /= 10;
            Thread.Sleep(2000);
            {
                Console.WriteLine("Testing one way message send speed (IP: 1350 bytes)...");
                var(client, server) = CreateAndInitialize(1350);
                var messagesToSend = Enumerable.Range(0, messageCount).Select(_ => rng.Generate(1300)).ToArray();
                var messagesSent   = new List <byte[]>(messageCount);
                var m1             = client.Send(new byte[16]);
                var m2             = client.Send(new byte[16]);
                var m3             = client.Send(new byte[16]);
                sw.Reset();
                sw.Start();
                for (int i = 0; i < messageCount; i++)
                {
                    messagesSent.Add(client.Send(messagesToSend[i]));
                }
                sw.Stop();
                Console.WriteLine($"Took {sw.Elapsed.TotalSeconds:F2}s ({messageCount / sw.Elapsed.TotalSeconds:F0}/s)");
                Console.WriteLine($"Bandwidth: { messagesToSend.Sum(x => x.Length * 8) / sw.Elapsed.TotalSeconds / (1024 * 1024):F0} Mbps");


                Thread.Sleep(1000);
                Console.WriteLine("Testing one way message receive speed (IP: 1350 bytes)...");
                server.Receive(m1);
                server.Receive(m2);
                server.Receive(m3);
                sw.Reset();
                sw.Start();
                for (int i = 0; i < messageCount; i++)
                {
                    server.Receive(messagesSent[i]);
                }
                sw.Stop();
                Console.WriteLine($"Took {sw.Elapsed.TotalSeconds:F2}s ({messageCount / sw.Elapsed.TotalSeconds:F0}/s)");
                Console.WriteLine($"Bandwidth: { messagesToSend.Sum(x => x.Length * 8) / sw.Elapsed.TotalSeconds / (1024 * 1024):F0} Mbps");
            }

            Thread.Sleep(1000);
            {
                Console.WriteLine("Testing ECDHratchet speed...");
                var(client, server) = CreateAndInitialize(1350);
                var messagesToSend = Enumerable.Range(0, messageCount / 4000).Select(_ => rng.Generate(32)).ToArray();
                server.Receive(client.Send(new byte[32]));
                client.Receive(server.Send(new byte[32]));
                sw.Reset();
                sw.Start();
                for (int i = 0; i < messageCount / 4000; i++)
                {
                    var m1 = client.Send(messagesToSend[i]);
                    server.Receive(m1);
                    var m2 = server.Send(messagesToSend[i]);
                    client.Receive(m2);
                }
                sw.Stop();
                Console.WriteLine($"Took {sw.Elapsed.TotalSeconds:F2}s ({(messageCount / 2000) / sw.Elapsed.TotalSeconds:F0}/s)");
            }

            messageCount *= 10;
            Thread.Sleep(1000);
            {
                var(client, server) = CreateAndInitialize();
                var              clientMessages           = new HashSet <byte[]>(Enumerable.Range(0, messageCount).Select(_ => rng.Generate(32)));
                var              serverMessages           = new HashSet <byte[]>(Enumerable.Range(0, messageCount).Select(_ => rng.Generate(32)));
                Queue <byte[]>   clientMessagesToSend     = new Queue <byte[]>(clientMessages);
                Queue <byte[]>   serverMessagesToSend     = new Queue <byte[]>(serverMessages);
                var              messagesSentFromClient   = new Queue <byte[]>();
                var              messagesSentFromServer   = new Queue <byte[]>();
                HashSet <byte[]> messagesReceivedByClient = new HashSet <byte[]>();
                HashSet <byte[]> messagesReceivedByServer = new HashSet <byte[]>();

                byte[] DoubleInSize(byte[] payload) => payload.Concat(payload).ToArray();

                int clientSent = 0, serverSent = 0, clientReceived = 0, serverReceived = 0, clientDropped = 0, serverDropped = 0;
                Console.WriteLine($"Sending {messageCount}/{clientDropChance:P0} and {messageCount}/{serverDropChance:P0}");

                sw.Reset();
                sw.Start();
                double oldTime = 0;
                int    oldCnt  = 0;
                for (int i = 0; ; i++)
                {
                    bool anyMessagesToReceive = messagesSentFromClient.TryPeek(out var _) || messagesSentFromServer.TryPeek(out var _);
                    bool anyMessagesToSend    = clientMessagesToSend.TryPeek(out var _) || serverMessagesToSend.TryPeek(out var _);
                    if (!anyMessagesToReceive && !anyMessagesToSend)
                    {
                        break;
                    }

                    if (i % 1000 == 0)
                    {
                        var totalReceived = clientReceived + serverReceived + clientDropped + serverDropped;
                        var totalAll      = messageCount + messageCount;
                        var percentage    = (double)totalReceived / totalAll;

                        var newTime   = sw.Elapsed.TotalSeconds;
                        var deltaTime = newTime - oldTime;
                        var deltaCnt  = totalReceived - oldCnt;

                        double perSecond = 0;
                        if (oldTime != 0)
                        {
                            perSecond = deltaCnt / deltaTime;
                        }
                        Console.Write($"\r{percentage:P0} - c: {clientSent}/{clientDropped} -> {serverReceived}  s: {serverSent}/{serverDropped} -> {clientReceived}   ({perSecond:F0}/s)  ");

                        oldCnt  = totalReceived;
                        oldTime = newTime;
                    }

                    var    clientOrServer = r.Next(2);
                    var    sendOrReceive  = r.Next(2);
                    double ratio          = (double)messageCount / messageCount;
                    int    maxClient      = 100;
                    int    maxServer      = (int)(100 / ratio);
                    var    maxMessages    = r.Next(clientOrServer == 0 ? maxClient : maxServer) + 1;

                    if (anyMessagesToSend && (sendOrReceive == 0 || !anyMessagesToReceive))
                    {
                        if (clientOrServer == 0) // send from client
                        {
                            while (maxMessages-- > 0)
                            {
                                clientMessagesToSend.TryDequeue(out var payload);
                                if (payload != null)
                                {
                                    payload = r.Next(10) > 7 ? DoubleInSize(payload) : payload;
                                    var message = client.Send(payload);
                                    if (r.NextDouble() > clientDropChance)
                                    {
                                        clientSent++;
                                        messagesSentFromClient.Enqueue(message);
                                    }
                                    else
                                    {
                                        clientDropped++;
                                    }
                                }
                            }
                        }
                        else
                        {
                            while (maxMessages-- > 0)
                            {
                                serverMessagesToSend.TryDequeue(out var payload);
                                if (payload != null)
                                {
                                    payload = r.Next(10) > 7 ? DoubleInSize(payload) : payload;
                                    var message = server.Send(payload);
                                    if (r.NextDouble() > serverDropChance)
                                    {
                                        serverSent++;
                                        messagesSentFromServer.Enqueue(message);
                                    }
                                    else
                                    {
                                        serverDropped++;
                                    }
                                }
                            }
                        }
                    }
                    else
                    {
                        if (clientOrServer != 0)  // receive by client
                        {
                            while (maxMessages-- > 0)
                            {
                                messagesSentFromServer.TryDequeue(out var message);
                                if (message != null)
                                {
                                    var payload = client.Receive(message).Payload;
                                    messagesReceivedByClient.Add(payload);
                                    clientReceived++;
                                }
                            }
                        }
                        else // receive by server
                        {
                            while (maxMessages-- > 0)
                            {
                                messagesSentFromClient.TryDequeue(out var message);
                                if (message != null)
                                {
                                    var payload = server.Receive(message).Payload;
                                    messagesReceivedByServer.Add(payload);
                                    serverReceived++;
                                }
                            }
                        }
                    }
                }

                Console.WriteLine("Done");
            }
        }
Пример #9
0
        public static async Task Run(CancellationToken cancellationToken)
        {
            // generate a key pair
            byte[] privateKey = KeyGeneration.GeneratePrivateKey();
            byte[] publicKey  = KeyGeneration.GetPublicKeyFromPrivateKey(privateKey);

            // configuring as a client with the default application key.
            // messages will be padded to 64 bytes and cannot exceed
            // 256 bytes.
            var config = new MicroRatchetConfiguration
            {
                ApplicationKey     = new byte[32],
                IsClient           = true,
                MaximumMessageSize = 256,
                MinimumMessageSize = 64
            };

            // create the MicroRatchet context
            var services = new BouncyCastleServices(privateKey);

            using var context = new MicroRatchetContext(services, config, null);

            Console.WriteLine($"Starting Client with public key: {publicKey.ToHexString()}");

            // Create UDP client. No connection since UDP is a
            // connectionless message based protocol. For the client
            // we don't specify a local endpoint.
            using var udp = new UdpClient();
            var serverEndpoint = new IPEndPoint(IPAddress.Loopback, PORT);

            // Step 1: Initialize
            while (!context.IsInitialized && !cancellationToken.IsCancellationRequested)
            {
                try
                {
                    // 1.1 Send initialization request
                    Console.WriteLine("Sending initialization request");
                    byte[] msg = context.InitiateInitialization();
                    await udp.SendAsync(msg, serverEndpoint, cancellationToken);

                    Console.WriteLine($"SENT {msg.Length} bytes INITIALIZATION REQUEST");

                    // 1.2 Receive initialization response
                    var timeout = CancellationTokenSource.CreateLinkedTokenSource(
                        cancellationToken,
                        new CancellationTokenSource(15000).Token).Token;
                    var receivedData = await udp.ReceiveAsync(timeout);

                    Console.WriteLine($"RECEIVED {receivedData.Buffer.Length} bytes FROM SERVER");
                    var res = context.Receive(receivedData.Buffer);

                    if (res.ToSendBack != null)
                    {
                        Console.WriteLine("Received initialization response.");
                        Console.WriteLine($"Server public key: {context.GetRemotePublicKey().ToHexString()}");
                        Console.WriteLine("Sending first message");
                        // 1.3 Send first request
                        await udp.SendAsync(res.ToSendBack, serverEndpoint, cancellationToken);

                        Console.WriteLine($"SENT BACK {res.ToSendBack.Length} bytes");

                        // 1.4 Receive first response
                        timeout = CancellationTokenSource.CreateLinkedTokenSource(
                            cancellationToken,
                            new CancellationTokenSource(15000).Token).Token;
                        receivedData = await udp.ReceiveAsync(timeout);

                        Console.WriteLine($"RECEIVED {receivedData.Buffer.Length} bytes FROM SERVER");
                        res = context.Receive(receivedData.Buffer);
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine($"An exception was encountered: {ex.Message}");
                }
            }

            // the context is now initialized and message can be sent back and forth
            // as needed. Messages being dropped or received out of order does not
            // affect subsequent messages.
            if (!cancellationToken.IsCancellationRequested)
            {
                Console.WriteLine("Client initialized");
                Console.WriteLine("Type stuff in and press enter to send to the server.\n\n");

                // in order to get the console, udp stuff, and MR stuff to work
                // together (even though nothing was written for async), we need
                // some synchronization.
                // A background thread reads from the console and pushes messages
                // into a queue which then in turn get sent to the server by the
                // Send task.
                // A receive task handles messages from the server


                // The receive task handles incoming UDP messages.
                var messages  = new ConcurrentQueue <string>();
                var semaphore = new SemaphoreSlim(0);
                async Task ReceiveTask()
                {
                    while (!cancellationToken.IsCancellationRequested)
                    {
                        var received = await udp.ReceiveAsync(cancellationToken);

                        Console.WriteLine($"RECEIVED {received.Buffer.Length} bytes");

                        try
                        {
                            // pass the received data to the MR context
                            var message = context.Receive(received.Buffer);

                            // The message is always padded to the minimum message size,
                            // so read the incoming message as a null-terminated
                            // string.
                            string msg = message.Payload.DecodeNullTerminatedString();

                            // Print the decrypted and decoded message to the console
                            Console.WriteLine($"RECEIVED MESSAGE: {msg}");
                        }
                        catch (Exception ex)
                        {
                            Console.WriteLine($"An exception was encountered when receiving a message: {ex}");
                        }
                    }
                }

                // the send task dequeues messages, encrypts, and sends
                // them to the server endpoint as UDP messages.
                async Task SendTask()
                {
                    while (!cancellationToken.IsCancellationRequested)
                    {
                        // wait for a message
                        await semaphore.WaitAsync();

                        messages.TryDequeue(out var payload);

                        // encrypt the message using the context. The message
                        // will be padded to the minimum configured message size.
                        var payloadBytes = Encoding.UTF8.GetBytes(payload);
                        var message      = context.Send(payloadBytes);

                        // send as UDP message to the server endpoint.
                        await udp.SendAsync(message, serverEndpoint, cancellationToken);

                        Console.WriteLine($"SENT {payloadBytes.Length} bytes PAYLOAD, resulting in {message.Length} bytes ENCRYPTED MESSAGE");
                    }
                }

                // The console thread reades lines one at a time and
                // enqueues them for sending.
                var consoleReadThread = new Thread(_ =>
                {
                    for (; ;)
                    {
                        messages.Enqueue(Console.ReadLine());
                        semaphore.Release();
                    }
                });
                // background threads are terminated when the program exits
                consoleReadThread.IsBackground = true;
                consoleReadThread.Start();

                await Task.WhenAll(ReceiveTask(), SendTask());
            }
        }
Пример #10
0
        public void ClientInitializationRestartTest()
        {
            // this test simulates a client timeout during initialization. When this
            // happens the client will restart initialization. The test checks that
            // the server and client will behave properly no matter at what point
            // during initialization the packet was dropped.

            BouncyCastleServices clientServices = new BouncyCastleServices(KeyGeneration.GeneratePrivateKey());
            BouncyCastleServices serverServices = new BouncyCastleServices(KeyGeneration.GeneratePrivateKey());


            for (int i = 0; i < 4; i++)
            {
                var client = new MicroRatchetContext(clientServices, true);
                var server = new MicroRatchetContext(serverServices, false);

                {
                    var clientInitPacket = client.InitiateInitialization();
                    if (i == 0)
                    {
                        goto restart;
                    }
                    var responsePacket = server.Receive(clientInitPacket).ToSendBack;
                    if (i == 1)
                    {
                        goto restart;
                    }
                    var firstPacket = client.Receive(responsePacket).ToSendBack;
                    if (i == 2)
                    {
                        goto restart;
                    }
                    var firstResponse = server.Receive(firstPacket).ToSendBack;
                    if (i == 3)
                    {
                        goto restart;
                    }
                    client.Receive(firstResponse);
                }

restart:
                {
                    var clientInitPacket = client.InitiateInitialization();
                    var responsePacket   = server.Receive(clientInitPacket).ToSendBack;
                    var firstPacket      = client.Receive(responsePacket).ToSendBack;
                    var firstResponse    = server.Receive(firstPacket).ToSendBack;
                    var lastResult       = client.Receive(firstResponse).ToSendBack;

                    Assert.Null(lastResult);
                }

                var    rng      = new RandomNumberGenerator();
                byte[] message1 = rng.Generate(32);
                byte[] message2 = rng.Generate(32);
                var    m1       = client.Send(message1);
                var    p1       = server.Receive(m1).Payload;
                var    m2       = server.Send(message2);
                var    p2       = client.Receive(m2).Payload;
                Assert.Equal(message1, p1);
                Assert.Equal(message2, p2);
            }
        }
Пример #11
0
        public void HotReinitialization()
        {
            BouncyCastleServices clientServices = new BouncyCastleServices(KeyGeneration.GeneratePrivateKey());
            BouncyCastleServices serverServices = new BouncyCastleServices(KeyGeneration.GeneratePrivateKey());

            var client = new MicroRatchetContext(clientServices, true, 1000);
            var server = new MicroRatchetContext(serverServices, false, 1000);

            byte[] cs, ss;

            // initialize
            {
                var clientInitPacket = client.InitiateInitialization();
                var responsePacket   = server.Receive(clientInitPacket).ToSendBack;
                var firstPacket      = client.Receive(responsePacket).ToSendBack;
                var firstResponse    = server.Receive(firstPacket).ToSendBack;
                var lastResult       = client.Receive(firstResponse).ToSendBack;
                cs = client.SaveStateAsByteArray();
                ss = server.SaveStateAsByteArray();
            }

            // now we're hot
            client = new MicroRatchetContext(clientServices, true, 80, stateBytes: cs);
            server = new MicroRatchetContext(serverServices, false, 80, stateBytes: ss);
            {
                RandomNumberGenerator rng = new RandomNumberGenerator();
                byte[] message1           = rng.Generate(32);
                byte[] message2           = rng.Generate(32);
                byte[] message3           = rng.Generate(32);

                var pl1 = client.Send(message1);
                var pl2 = client.Send(message2);
                var pl3 = client.Send(message3);

                var r1 = server.Receive(pl1).Payload;
                var r2 = server.Receive(pl2).Payload;
                var r3 = server.Receive(pl3).Payload;

                Assert.Equal(message1, r1);
                Assert.Equal(message2, r2);
                Assert.Equal(message3, r3);

                cs = client.SaveStateAsByteArray();
                ss = server.SaveStateAsByteArray();
            }

            // oh noes! Client fail! reinitialize
            client = new MicroRatchetContext(clientServices, true, 1000);
            server = new MicroRatchetContext(serverServices, false, 1000, stateBytes: ss);
            {
                var clientInitPacket = client.InitiateInitialization();
                var responsePacket   = server.Receive(clientInitPacket).ToSendBack;
                var firstPacket      = client.Receive(responsePacket).ToSendBack;
                var firstResponse    = server.Receive(firstPacket).ToSendBack;
                var lastResult       = client.Receive(firstResponse).ToSendBack;
                cs = client.SaveStateAsByteArray();
                ss = server.SaveStateAsByteArray();
            }

            // now we're hot AGAIN
            client = new MicroRatchetContext(clientServices, true, 80, stateBytes: cs);
            server = new MicroRatchetContext(serverServices, false, 80, stateBytes: ss);
            {
                RandomNumberGenerator rng = new RandomNumberGenerator();
                byte[] message1           = rng.Generate(32);
                byte[] message2           = rng.Generate(32);
                byte[] message3           = rng.Generate(32);

                var pl1 = client.Send(message1);
                var pl2 = client.Send(message2);
                var pl3 = client.Send(message3);

                var r1 = server.Receive(pl1).Payload;
                var r2 = server.Receive(pl2).Payload;
                var r3 = server.Receive(pl3).Payload;

                Assert.Equal(message1, r1);
                Assert.Equal(message2, r2);
                Assert.Equal(message3, r3);

                cs = client.SaveStateAsByteArray();
                ss = server.SaveStateAsByteArray();
            }
        }
Пример #12
0
        public void ClientInitStateTest()
        {
            var clientServices = new BouncyCastleServices(KeyGeneration.GeneratePrivateKey());
            var serverServices = new BouncyCastleServices(KeyGeneration.GeneratePrivateKey());

            byte[] cs, ss;

            RandomNumberGenerator rng = new RandomNumberGenerator();

            byte[] message1 = rng.Generate(64);
            byte[] message2 = rng.Generate(64);
            byte[] message3 = rng.Generate(64);

            var client = new MicroRatchetContext(clientServices, true);
            var kex    = clientServices.KeyAgreementFactory;

            var clientInitPacket = client.InitiateInitialization();

            cs = client.SaveStateAsByteArray();
            {
                var ts = ClientState.Load(cs, kex, ks).StoreAsByteArray(5);
                Assert.Equal(ts, cs);
            }

            var server         = new MicroRatchetContext(serverServices, false);
            var responsePacket = server.Receive(clientInitPacket).ToSendBack;

            ss = server.SaveStateAsByteArray();
            {
                var ts = ServerState.Load(ss, kex, ks).StoreAsByteArray(5);
                Assert.Equal(ts, ss);
            }


            client = new MicroRatchetContext(clientServices, true, stateBytes: cs);
            var firstPacket = client.Receive(responsePacket).ToSendBack;

            cs = client.SaveStateAsByteArray();
            {
                var ts = ClientState.Load(cs, kex, ks).StoreAsByteArray(5);
                Assert.Equal(ts, cs);
            }

            server = new MicroRatchetContext(serverServices, false, stateBytes: ss);
            var firstResponse = server.Receive(firstPacket).ToSendBack;

            ss = server.SaveStateAsByteArray();
            {
                var ts = ServerState.Load(ss, kex, ks).StoreAsByteArray(5);
                Assert.Equal(ts, ss);
            }

            client = new MicroRatchetContext(clientServices, true, stateBytes: cs);
            var lastResult = client.Receive(firstResponse).ToSendBack;

            cs = client.SaveStateAsByteArray();
            {
                var ts = ClientState.Load(cs, kex, ks).StoreAsByteArray(5);
                Assert.Equal(ts, cs);
            }


            client = new MicroRatchetContext(clientServices, true, 80, stateBytes: cs);
            var pl1 = client.Send(message1);

            cs = client.SaveStateAsByteArray();
            {
                var ts = ClientState.Load(cs, kex, ks).StoreAsByteArray(5);
                Assert.Equal(ts, cs);
            }

            client = new MicroRatchetContext(clientServices, true, 80, stateBytes: cs);
            var pl2 = client.Send(message2);

            cs = client.SaveStateAsByteArray();
            {
                var ts = ClientState.Load(cs, kex, ks).StoreAsByteArray(5);
                Assert.Equal(ts, cs);
            }

            client = new MicroRatchetContext(clientServices, true, 80, stateBytes: cs);
            var pl3 = client.Send(message3);

            cs = client.SaveStateAsByteArray();
            {
                var ts = ClientState.Load(cs, kex, ks).StoreAsByteArray(5);
                Assert.Equal(ts, cs);
            }


            server = new MicroRatchetContext(serverServices, false, 80, stateBytes: ss);
            var r1 = server.Receive(pl1).Payload;

            ss = server.SaveStateAsByteArray();
            {
                var ts = ServerState.Load(ss, kex, ks).StoreAsByteArray(5);
                Assert.Equal(ts, ss);
            }

            server = new MicroRatchetContext(serverServices, false, 80, stateBytes: ss);
            var r2 = server.Receive(pl2).Payload;

            ss = server.SaveStateAsByteArray();
            {
                var ts = ServerState.Load(ss, kex, ks).StoreAsByteArray(5);
                Assert.Equal(ts, ss);
            }

            server = new MicroRatchetContext(serverServices, false, 80, stateBytes: ss);
            var r3 = server.Receive(pl3).Payload;

            ss = server.SaveStateAsByteArray();
            {
                var ts = ServerState.Load(ss, kex, ks).StoreAsByteArray(5);
                Assert.Equal(ts, ss);
            }


            Assert.Equal(message1, r1);
            Assert.Equal(message2, r2);
            Assert.Equal(message3, r3);

            Assert.Null(lastResult);
        }
Пример #13
0
        public static async Task Run(CancellationToken cancellationToken)
        {
            // generate a key pair
            byte[] privateKey = KeyGeneration.GeneratePrivateKey();
            byte[] publicKey  = KeyGeneration.GetPublicKeyFromPrivateKey(privateKey);

            // configuring as a server with the default application key.
            // messages will be padded to 64 bytes and cannot exceed
            // 256 bytes.
            var config = new MicroRatchetConfiguration
            {
                ApplicationKey     = new byte[32],
                IsClient           = false,
                MaximumMessageSize = 256,
                MinimumMessageSize = 64
            };

            // create the MicroRatchet context
            var services = new BouncyCastleServices(privateKey);

            using var context = new MicroRatchetContext(services, config, null);

            Console.WriteLine($"Starting Server with public key: {publicKey.ToHexString()}");

            // Create UDP client. For the server we set
            // the local endpoint to be localhost,
            // listening on the configured port.
            var        serverEndpoint = new IPEndPoint(IPAddress.Loopback, PORT);
            IPEndPoint clientEndpoint = null;

            using var udp = new UdpClient(serverEndpoint);

            if (!cancellationToken.IsCancellationRequested)
            {
                // in order to get the console, udp stuff, and MR stuff to work
                // together (even though nothing was written for async), we need
                // some synchronization.
                // A background thread reads from the console and pushes messages
                // into a queue which then in turn get sent to the server by the
                // Send task.
                // A receive task handles messages from the server


                // The receive task handles incoming UDP messages.
                var messages  = new ConcurrentQueue <string>();
                var semaphore = new SemaphoreSlim(0);
                async Task ReceiveTask()
                {
                    while (!cancellationToken.IsCancellationRequested)
                    {
                        var received = await udp.ReceiveAsync(cancellationToken);

                        Console.WriteLine($"RECEIVED {received.Buffer.Length} bytes");

                        try
                        {
                            // pass the received data to the MR context
                            var message = context.Receive(received.Buffer);

                            // if ToSendBack is not null, the context has accepted
                            // an incoming initialization message and now is bound
                            // to the session from that client key.
                            if (message.ToSendBack != null)
                            {
                                // send the response back
                                await udp.SendAsync(message.ToSendBack, message.ToSendBack.Length, received.RemoteEndPoint);

                                Console.WriteLine($"SENT {message.ToSendBack.Length} bytes RESPONSE");

                                if (context.IsInitialized)
                                {
                                    // message.ToSendBack != null && context.IsInitialized
                                    // typically happens once per session.
                                    clientEndpoint = received.RemoteEndPoint;
                                    Console.WriteLine($"Server initialized with remote public key {context.GetRemotePublicKey().ToHexString()}.");
                                    Console.WriteLine("Type stuff in and press enter to send to the client.\n\n");
                                }
                            }
                            else if (message.Payload != null)
                            {
                                // if a payload is given, the message contains
                                // data sent by the client, which we print to the console.

                                // The message is always padded to the minimum message size,
                                // so read the incoming message as a null-terminated
                                // string.
                                string msg = message.Payload.DecodeNullTerminatedString();

                                // Print the decrypted and decoded message to the console
                                Console.WriteLine($"RECEIVED MESSAGE: {msg}");
                            }
                        }
                        catch (Exception ex)
                        {
                            // one exception you would see in this situation is if second client
                            // tries to initialize a session. Because the context is bound to a remote
                            // public key as soon as a message comes in, and this demo application
                            // contains no logic to handle that situation, it will simply stay bound
                            // to the first session and throw an exception if another client tries to
                            // connect.
                            Console.WriteLine($"An exception was encountered when receiving a message: {ex}");
                        }
                    }
                }

                // the send task dequeues messages, encrypts, and sends
                // them to the server endpoint as UDP messages.
                async Task SendTask()
                {
                    while (!cancellationToken.IsCancellationRequested)
                    {
                        // wait for a message
                        await semaphore.WaitAsync();

                        messages.TryDequeue(out var payload);

                        // encrypt the message using the context. The message
                        // will be padded to the minimum configured message size.
                        var payloadBytes = Encoding.UTF8.GetBytes(payload);
                        var message      = context.Send(payloadBytes);

                        // send as UDP message to the server endpoint.
                        await udp.SendAsync(message, clientEndpoint, cancellationToken);

                        Console.WriteLine($"SENT {payloadBytes.Length} bytes PAYLOAD, resulting in {message.Length} bytes ENCRYPTED MESSAGE");
                    }
                }

                // The console thread reades lines one at a time and
                // enqueues them for sending.
                var consoleReadThread = new Thread(_ =>
                {
                    for (; ;)
                    {
                        string line = Console.ReadLine();
                        if (clientEndpoint != null)
                        {
                            messages.Enqueue(line);
                            semaphore.Release();
                        }
                        else
                        {
                            Console.WriteLine("Cannot send message as no client has initialized a session");
                        }
                    }
                });
                // background threads are terminated when the program exits
                consoleReadThread.IsBackground = true;
                consoleReadThread.Start();

                await Task.WhenAll(ReceiveTask(), SendTask());
            }
        }
Пример #14
0
        public void ReferenceTest1()
        {
            var message1 = new byte[] { 0x3c, 0x07, 0x3f, 0x70, 0xe7, 0xee, 0x7f, 0x88, 0x34, 0x14, 0x8e, 0x1a, 0xb8, 0xb4, 0xd4, 0x33 };
            var message2 = new byte[] { 0x73, 0x17, 0xa6, 0x4a, 0x5c, 0xb5, 0x1c, 0x5f, 0xda, 0x61, 0x33, 0x4e, 0xde, 0x38, 0x54, 0x97, 0xc6, 0x95, 0x14, 0xc6, 0x4b, 0x60, 0xf8, 0xd5, 0x32, 0x37, 0x38, 0xc8, 0x01, 0x38, 0x28, 0x8b };
            var message3 = new byte[] { 0x32, 0x12, 0x57, 0x18, 0x87, 0xa2, 0x26, 0x2a, 0x91, 0x3e, 0xf1, 0xa5, 0x07, 0x76, 0x0f, 0x6d, 0xa2, 0x09, 0x6a, 0x7b, 0xa4, 0x59, 0x5d, 0xc6, 0x2b, 0xca, 0x0e, 0xce, 0xd2, 0xf7, 0xb3, 0x4f, 0x01, 0x52, 0x1c, 0x07, 0x59, 0x06, 0x7b, 0x2a, 0x4c, 0x57, 0xeb, 0x45, 0x64, 0x37, 0x9c, 0xe5, 0x22, 0xcd, 0x77, 0x19, 0x29, 0xe3, 0x6e, 0x21, 0xbf, 0x11, 0x40, 0x6a, 0x89, 0xc8, 0x8f, 0xb0, 0x2b, 0x8e, 0x2a, 0x33, 0x2c, 0xce, 0x24, 0x9f, 0xed, 0xec, 0x3a, 0x50, 0xae, 0x69, 0xcd, 0x99, 0xac, 0x92, 0xd7, 0xaa, 0xe7, 0xca, 0xbf, 0x7b, 0xc4, 0x36, 0xd7, 0xd8, 0x16, 0xf4, 0x59, 0x30, 0xc4, 0x8c, 0x10, 0x66, 0x6a, 0xb6, 0xf2, 0x18, 0x69, 0x8c, 0xae, 0x38, 0x32, 0x54, 0x12, 0xcb, 0x5c, 0xc7, 0x92, 0x3b, 0x3a, 0x71, 0xa4, 0xfd, 0x81, 0x46, 0xf6, 0x7d, 0xf9, 0x97, 0xeb, 0xf2, 0x5c, 0xfc, 0x4f, 0x3c, 0x9c, 0x6f, 0xd8, 0x42, 0x24, 0x11, 0x16, 0xbd, 0xaa, 0x38, 0x0f, 0x0e, 0xe2, 0x92, 0x83, 0x54, 0x0f, 0xd3, 0x6e, 0xe5, 0x2a, 0x36, 0x77, 0x14, 0x80, 0x5e, 0xf9, 0x1f, 0x5b, 0xd0, 0xb5, 0xb5, 0x57, 0x5b, 0xf1, 0x79, 0xf8, 0x30, 0x74, 0xb6, 0xbf, 0xcb, 0x4c, 0x66, 0x32, 0xeb, 0x3a, 0xed, 0x80, 0x5b, 0xd6, 0xd8, 0x57, 0xf8, 0xec, 0xf8, 0x53, 0x05, 0x9a, 0xcc, 0x7b, 0x73, 0x9a, 0xfc, 0xe3, 0x40, 0xef, 0xbb, 0x96, 0x7a, 0x98, 0x9d, 0x73, 0x1b, 0x88, 0x40, 0xbd, 0x94, 0xfc, 0x21, 0x0b, 0x0c, 0xba, 0xf6, 0xc8, 0x53, 0x3a, 0xdf, 0x1a, 0x87, 0xdc, 0xfe, 0x15, 0xa7, 0xbc, 0x0e, 0x3b, 0x3a, 0x67, 0x3b, 0x40, 0xfd, 0xab, 0xa8, 0x75, 0xa0, 0xbf, 0x6a };

            var randomC = new byte[] { 0xd4, 0xf7, 0xd4, 0x89, 0x86, 0xdc, 0x90, 0xc8, 0x62, 0x5b, 0xb7, 0x8d, 0xc5, 0x25, 0x51, 0xd4, 0xc2, 0x1d, 0xf7, 0x81, 0x97, 0x33, 0x27, 0x6c, 0x37, 0x00, 0x8d, 0x3e, 0xf3, 0x27, 0xf8, 0xfe, 0x94, 0x44, 0xa0, 0x7f, 0xec, 0xb6, 0x35, 0xe4, 0x4a, 0xb8, 0xaf, 0x49, 0x87, 0x48, 0xfd, 0x6c, 0xdf, 0x77, 0x21, 0xbe, 0xfa, 0xfa, 0x3b, 0x3a, 0x3a, 0x40, 0x4c, 0x39, 0x06, 0xc6, 0x87, 0xcf, 0xc2, 0xff, 0xc0, 0x1e, 0xa2, 0x4e, 0x95, 0xc4, 0x45, 0xc1, 0xb1, 0x88, 0x2d, 0x78, 0x6d, 0xc6, 0xca, 0x4f, 0xf4, 0xff, 0x4e, 0xe3, 0x49, 0x8a, 0x07, 0x0d, 0x08, 0x11, 0xb4, 0xed, 0x19, 0xa3, 0xdb, 0xa8, 0x02, 0x4f, 0x3c, 0x1e, 0x39, 0xb0, 0x29, 0xc6, 0xa9, 0x24, 0xdc, 0x2d, 0x94, 0xf6, 0x08, 0x40, 0x29, 0xab, 0x9c, 0x48, 0xe9, 0x6f, 0x2b, 0x7e, 0xc1, 0xd8, 0x93, 0xde, 0x33, 0x51, 0x69, 0xcd, 0xf3, 0x91, 0xd9, 0x29, 0xa7, 0x96, 0x29, 0xdb, 0xc3, 0xcb, 0xa2, 0xa4, 0x40, 0x52, 0x83, 0x77, 0x5b, 0x48, 0xb5, 0xbf, 0xb7, 0xde, 0x78, 0x1e, 0xc3, 0xcb, 0xb6, 0x04, 0x97, 0xf6, 0x0f, 0x4b, 0x94, 0xc8, 0xc6, 0xa6, 0x6d, 0x6c, 0x09, 0x45, 0x72, 0x7e, 0x07, 0x1d, 0xc5, 0x77, 0xc8, 0x48, 0x21, 0xa2, 0xba, 0xad, 0xe0, 0x4d, 0xef, 0x4b, 0x4c, 0x55, 0x18, 0xed, 0x52, 0x32, 0x67, 0xea, 0x8d, 0x40, 0x2c, 0xab, 0x59, 0x96, 0x30, 0x49, 0x90, 0xb5, 0x19, 0xef, 0x86, 0xf9, 0x2e, 0x20, 0xa3, 0x4b, 0x8a, 0xfd, 0xe2, 0x9a, 0xfa, 0x99, 0x45, 0x84, 0x72, 0x7f, 0x50, 0x49, 0x85, 0xda, 0x08, 0x3d, 0x7f, 0x0d, 0xe6, 0x0d, 0x35, 0x31, 0xa2, 0x24, 0xda, 0x42, 0x2f, 0x69, 0x58, 0x8b, 0x4a, 0x61, 0xaf, 0xb2, 0x11, 0x4c, 0x36, 0x1a, 0x67, 0x38, 0xc5, 0xd0, 0xac, 0x0c };
            var randomS = new byte[] { 0xc9, 0x06, 0xbc, 0xd2, 0xe9, 0xdb, 0x8f, 0x5e, 0x47, 0x26, 0x91, 0xa0, 0xe4, 0xc9, 0xb3, 0x24, 0xf2, 0x9d, 0xfb, 0x2f, 0x33, 0xd7, 0x9c, 0x45, 0x1d, 0xc8, 0x68, 0xbf, 0x9a, 0xfa, 0xb6, 0x56, 0xa0, 0x1a, 0x84, 0xab, 0xdd, 0x53, 0xfc, 0x78, 0x46, 0x72, 0xdf, 0x3e, 0x49, 0x74, 0x76, 0x8c, 0xbf, 0xbf, 0x35, 0x2f, 0xe9, 0xd9, 0x91, 0x54, 0x0c, 0x5d, 0x80, 0x46, 0xb5, 0xee, 0x85, 0x6c, 0xee, 0xf8, 0x4a, 0x66, 0x1f, 0xac, 0xe2, 0x08, 0x14, 0xf6, 0x84, 0xdd, 0xe7, 0xb2, 0x86, 0x77, 0xdf, 0xd2, 0x53, 0x74, 0xb6, 0xd3, 0xce, 0xb7, 0x61, 0xdd, 0x23, 0x46, 0x4d, 0xf8, 0xfc, 0x0c, 0x9b, 0x02, 0xf3, 0x6f, 0x3f, 0x2f, 0x9a, 0x52, 0xaa, 0xc5, 0x67, 0x11, 0xbf, 0x89, 0x97, 0xf5, 0xb9, 0xc4, 0x5d, 0x25, 0x49, 0x68, 0x57, 0x80, 0x07, 0x3c, 0x21, 0x5a, 0x25, 0xaf, 0x23, 0xbc, 0x46, 0x8b, 0xc7, 0x97, 0xbe, 0xe5, 0xec, 0xfc, 0xd1, 0x9e, 0xde, 0x7d, 0x37, 0xce, 0x5f, 0x2e, 0x76, 0x9c, 0x81, 0x72, 0xfb, 0xe9, 0x01, 0x37, 0xde, 0x3a, 0xb5, 0xf1, 0x02, 0xc5, 0x6d, 0x19, 0xce, 0xdf, 0xda, 0xbb, 0xb1, 0xaa, 0x05, 0xcd, 0x80, 0x78, 0xc4, 0x1e, 0x72, 0x21, 0x72, 0x28, 0xe4, 0xce, 0xe1, 0x3b, 0x58, 0x66, 0x5b, 0x18, 0xaa, 0xe0, 0x12, 0x00, 0xfe, 0x11, 0xcf, 0x41, 0x8e, 0xc0, 0x89, 0xa2, 0x9d, 0x7c, 0x55, 0x78, 0x0b, 0x03, 0xb9, 0x63, 0x50, 0x2d, 0x44, 0x90, 0xd1, 0xf1, 0x36, 0xc9, 0x04, 0x8f, 0xcc, 0x1b, 0xc2, 0xef, 0x76, 0x3b, 0x11, 0x77, 0x59, 0xf4, 0x5b, 0xea, 0xdf, 0x56, 0xd4, 0x81, 0x8b, 0x36, 0xfd, 0x02, 0x06, 0xf1, 0x41, 0x4f, 0x47, 0xbc, 0x59, 0x57, 0x31, 0x9a, 0x1b, 0xfa, 0x8a, 0xf9, 0xd8, 0x3e, 0x0c, 0x28, 0x2c, 0xb1, 0xc2, 0x1d };

            var applicationKey = new byte[] { 0xef, 0x3f, 0xb4, 0x74, 0xe1, 0x41, 0x07, 0x76, 0xe5, 0xbf, 0x85, 0x94, 0xd2, 0x95, 0xb0, 0x5f, 0x3e, 0x04, 0xe2, 0x21, 0xce, 0x5a, 0x3e, 0xf3, 0xee, 0x40, 0xca, 0x33, 0x24, 0x78, 0xbb, 0x78 };
            var privateKeyC    = new byte[] { 0x47, 0x3e, 0x33, 0x6b, 0xa2, 0xc7, 0xfb, 0xae, 0xc3, 0x9f, 0x38, 0xd6, 0x2e, 0x3e, 0x8d, 0xda, 0xc8, 0x8f, 0x09, 0x0f, 0xb6, 0xbe, 0x85, 0xd7, 0x3c, 0xc5, 0xf6, 0x11, 0x39, 0xa6, 0x3b, 0xb0 };
            var privateKeyS    = new byte[] { 0x69, 0xb2, 0x36, 0x09, 0x02, 0x55, 0x3c, 0xf8, 0x65, 0x79, 0x79, 0xfb, 0xea, 0xc6, 0xcf, 0x80, 0x2d, 0x49, 0xd1, 0x30, 0x73, 0xd9, 0xa7, 0x11, 0x48, 0x4f, 0x42, 0x9f, 0x85, 0x12, 0x11, 0x40 };

            //var rng = new RandomNumberGenerator();
            //message1 = rng.Generate(16);
            //message2 = rng.Generate(32);
            //message3 = rng.Generate(256 - 16);
            //randomC = rng.Generate(256);
            //randomS = rng.Generate(256);
            //applicationKey = rng.Generate(32);
            //privateKeyC = KeyGeneration.GeneratePrivateKey();
            //privateKeyS = KeyGeneration.GeneratePrivateKey();

            //BytePrintHelper.PrintAsByteArray(nameof(message1), message1);
            //BytePrintHelper.PrintAsByteArray(nameof(message2), message2);
            //BytePrintHelper.PrintAsByteArray(nameof(message3), message3);
            //BytePrintHelper.PrintAsByteArray(nameof(randomC), randomC);
            //BytePrintHelper.PrintAsByteArray(nameof(randomS), randomS);
            //BytePrintHelper.PrintAsByteArray(nameof(applicationKey), applicationKey);
            //BytePrintHelper.PrintAsByteArray(nameof(privateKeyC), privateKeyC);
            //BytePrintHelper.PrintAsByteArray(nameof(privateKeyS), privateKeyS);

            var ec1  = new byte[] { 0xd4, 0xf7, 0xd4, 0x89, 0x86, 0xdc, 0x90, 0xc8, 0x62, 0x5b, 0xb7, 0x8d, 0xc5, 0x25, 0x51, 0xd4, 0xb1, 0x4b, 0xdd, 0x0d, 0x6f, 0xda, 0x36, 0x98, 0x3e, 0xb9, 0xd0, 0x1e, 0x90, 0x93, 0x7d, 0x7c, 0x3d, 0x96, 0x17, 0xe1, 0x9e, 0x13, 0xa8, 0xec, 0x29, 0x7f, 0xac, 0x75, 0xaf, 0xff, 0x65, 0xf7, 0x1a, 0xf8, 0xc3, 0x52, 0xa1, 0xb7, 0x6f, 0x8d, 0x37, 0x1b, 0xc5, 0xec, 0x53, 0x18, 0xfe, 0x42, 0x1e, 0x21, 0xf1, 0xf2, 0xbc, 0x36, 0x45, 0xee, 0xe4, 0x12, 0xb9, 0xb2, 0xac, 0x7e, 0x46, 0xd0, 0xe9, 0x7f, 0x43, 0xf3, 0xa9, 0xe8, 0xa5, 0xec, 0xf4, 0xcf, 0xa9, 0x27, 0x16, 0x72, 0x30, 0xd4, 0xb0, 0x42, 0x31, 0x71, 0xa5, 0xfc, 0xe6, 0x52, 0xe5, 0x56, 0x62, 0x26, 0x64, 0x3e, 0xe7, 0xa3, 0x39, 0x0a, 0x1f, 0x24, 0x2a, 0xac, 0xf8, 0xb5, 0x37, 0x2e, 0x1e, 0x90, 0x80, 0x36, 0x17, 0x2c, 0x71, 0x17, 0x31, 0xac, 0x25, 0x23, 0xdb, 0x2a, 0x2c, 0x42, 0x1e, 0x29, 0x34, 0x4c, 0x1b, 0x2d, 0xe9, 0x2c, 0x41, 0x81, 0xef, 0x95, 0x62, 0xeb, 0x95, 0xa0, 0x64, 0xf1 };
            var es2  = new byte[] { 0xc9, 0x06, 0xbc, 0xd2, 0xe9, 0xdb, 0x8f, 0x5e, 0x47, 0x26, 0x91, 0xa0, 0xe4, 0xc9, 0xb3, 0x24, 0x4a, 0xb3, 0x7d, 0xdc, 0x64, 0x3b, 0x1e, 0xb2, 0xa9, 0xc6, 0xcb, 0xba, 0x5c, 0x56, 0x26, 0x0e, 0x19, 0x39, 0x9f, 0x09, 0xa5, 0x36, 0xfc, 0x44, 0x76, 0xfc, 0x8d, 0xb6, 0x1d, 0xdd, 0x20, 0x2e, 0xd4, 0xf7, 0xd4, 0x89, 0x86, 0xdc, 0x90, 0xc8, 0x62, 0x5b, 0xb7, 0x8d, 0xc5, 0x25, 0x51, 0xd4, 0x6a, 0x42, 0x9b, 0x65, 0x66, 0xe3, 0x63, 0xe5, 0xe2, 0x9c, 0xe9, 0x36, 0xb3, 0xd6, 0xaf, 0xd0, 0xa6, 0x02, 0x38, 0x4e, 0xdf, 0x86, 0x7d, 0xf2, 0x8a, 0xfe, 0xf4, 0x5d, 0xe5, 0x87, 0xd9, 0x0e, 0x52, 0xd1, 0x12, 0x1b, 0xe5, 0x67, 0x5f, 0xec, 0xda, 0x61, 0x74, 0x70, 0x6d, 0x2c, 0x0e, 0x52, 0x87, 0x84, 0x9f, 0xcd, 0x25, 0x04, 0xc8, 0x6e, 0x87, 0xbf, 0x0a, 0x09, 0x2e, 0x31, 0x89, 0x12, 0xb8, 0x6d, 0x9e, 0x99, 0xee, 0xf5, 0x79, 0xb6, 0x98, 0xac, 0x4a, 0xe3, 0xb2, 0x12, 0xf4, 0xcb, 0xf0, 0xaa, 0xc8, 0x50, 0xf1, 0x40, 0xcb, 0x04, 0x73, 0xb6, 0x38, 0x5d, 0xbc, 0xcb, 0xbd, 0xff, 0xf9, 0xbb, 0xdc, 0x67, 0x78, 0xed, 0xd9, 0xbb, 0x52, 0x72, 0x3e, 0x1b, 0xe9, 0x20, 0x87, 0x79, 0x09, 0xfc, 0x29, 0xbf, 0x4e, 0x62, 0x9c, 0x13, 0x31, 0x21, 0xc9, 0x71, 0xd2, 0x66, 0x5e, 0x47, 0xca, 0xee, 0xa2, 0x5f, 0x4a, 0x95, 0xb3, 0x67, 0x36, 0x00, 0x73, 0x19, 0x4f, 0x86, 0xab, 0xf1, 0x3e, 0xd4, 0xce, 0x0c, 0x9a, 0xf3, 0x68, 0x03, 0x8a, 0x36, 0x79, 0x6e, 0xb6, 0x0a, 0x7d, 0x59, 0x64, 0xf1, 0xd0, 0x32, 0xa9, 0x40, 0x94, 0x93, 0x71, 0x5e, 0x36, 0x72 };
            var ec3  = new byte[] { 0xa0, 0xd7, 0xb7, 0xfa, 0x7e, 0x1b, 0xbc, 0xad, 0xce, 0x9b, 0x4b, 0xdd, 0xfc, 0x27, 0x3f, 0x06, 0x2e, 0xef, 0x91, 0xf3, 0x4e, 0x5b, 0xd9, 0xfd, 0x86, 0x81, 0x4f, 0x1f, 0xa9, 0x3f, 0x26, 0xd4, 0x0d, 0xdc, 0x48, 0x5c, 0x0b, 0xe8, 0xbf, 0x70, 0xa5, 0xe2, 0xc5, 0xa9, 0x62, 0xde, 0xf9, 0x0b, 0xbc, 0xe6, 0xcd, 0x9a, 0x47, 0x4c, 0x99, 0xa8, 0xe8, 0x11, 0x9c, 0x00, 0x0d, 0x80, 0x68, 0xdf };
            var es4  = new byte[] { 0x29, 0xa8, 0xbb, 0x57, 0x5f, 0xa5, 0x00, 0x07, 0x8a, 0x4a, 0x56, 0x47, 0x2b, 0xc5, 0x50, 0x3f, 0x3b, 0x7f, 0xe8, 0x5d, 0x6e, 0x7f, 0x8d, 0x5e, 0x98, 0x68, 0x90, 0x9a, 0x2c, 0x5b, 0xb9, 0x89 };
            var ec6  = new byte[] { 0x29, 0x3f, 0x3d, 0x0f, 0xf8, 0xad, 0x1f, 0xe2, 0x17, 0x69, 0x8f, 0x26, 0xf4, 0x40, 0xe0, 0x87, 0x25, 0xe1, 0xcc, 0x1b, 0x91, 0x89, 0x70, 0x88, 0x38, 0xbc, 0x49, 0x90, 0x2f, 0x68, 0x9f, 0xb2, 0xcc, 0x3b, 0x43, 0xd7, 0xea, 0x95, 0xf7, 0xd3, 0x53, 0x44, 0x41, 0x7b, 0x80, 0x0c, 0xe5, 0x2d, 0x8d, 0x97, 0x29, 0x40, 0xac, 0xd0, 0x5d, 0xbd, 0xea, 0xec, 0xaf, 0xa3, 0xcb, 0x7a, 0x77, 0x77 };
            var es7  = new byte[] { 0x3c, 0x07, 0x3f, 0x70, 0xe7, 0xee, 0x7f, 0x88, 0x34, 0x14, 0x8e, 0x1a, 0xb8, 0xb4, 0xd4, 0x33 };
            var es8  = new byte[] { 0x17, 0x57, 0x08, 0x06, 0xa3, 0x70, 0x18, 0xf2, 0xda, 0xaf, 0x2e, 0x87, 0x7d, 0xc8, 0xa5, 0x3e, 0xc2, 0xcb, 0x63, 0x40, 0xaa, 0x9a, 0xfb, 0xd7, 0x9a, 0x7b, 0xca, 0xe5, 0xfe, 0x3e, 0xed, 0x04, 0xaf, 0x56, 0x97, 0x2c, 0x9e, 0x3a, 0xea, 0xaa, 0x68, 0x9b, 0x4d, 0xd8, 0x9f, 0xe7, 0x25, 0x15, 0xb5, 0xf6, 0x69, 0x1a, 0xde, 0x61, 0xe2, 0x6e, 0xe9, 0x19, 0xd7, 0x4b, 0x05, 0x01, 0xaf, 0x3d, 0x0d, 0x2b, 0x35, 0x9a, 0xf3, 0x2c, 0xee, 0xeb, 0x0a, 0x68, 0x47, 0xe5, 0xd2, 0xf2, 0xee, 0x90 };
            var ec9  = new byte[] { 0x73, 0x17, 0xa6, 0x4a, 0x5c, 0xb5, 0x1c, 0x5f, 0xda, 0x61, 0x33, 0x4e, 0xde, 0x38, 0x54, 0x97, 0xc6, 0x95, 0x14, 0xc6, 0x4b, 0x60, 0xf8, 0xd5, 0x32, 0x37, 0x38, 0xc8, 0x01, 0x38, 0x28, 0x8b };
            var ec10 = new byte[] { 0xf7, 0x11, 0x86, 0xd0, 0x87, 0x67, 0xf2, 0xf1, 0x98, 0x75, 0xe4, 0x12, 0xd6, 0xff, 0x75, 0x4d, 0xfd, 0x23, 0x8a, 0xf8, 0x71, 0x00, 0x0f, 0xe1, 0x19, 0x74, 0x17, 0x0d, 0xc0, 0xf1, 0xb1, 0x75, 0x2b, 0x74, 0xf7, 0x5e, 0xd2, 0x58, 0x01, 0x2a, 0xa4, 0x39, 0x51, 0xe3, 0x6f, 0x5b, 0x24, 0x01, 0x19, 0x86, 0x9a, 0xf6, 0x8c, 0x37, 0x43, 0xb1, 0xfd, 0x0a, 0xc0, 0x37, 0xd0, 0x02, 0x0a, 0xc8, 0x1c, 0x74, 0x2b, 0x26, 0x17, 0xde, 0x34, 0x0a, 0x21, 0x8b, 0xda, 0x1f, 0xae, 0x19, 0x81, 0x14, 0x97, 0x60, 0x62, 0x38, 0x48, 0xb0, 0x99, 0x3e, 0x82, 0x19, 0xad, 0xdd, 0xb3, 0x4e, 0x63, 0x9f, 0x4f, 0x25, 0xe7, 0x43, 0xe7, 0x30, 0x1b, 0xde, 0x14, 0x8b, 0x55, 0xd7, 0xe9, 0x69, 0x75, 0x03, 0x36, 0xce, 0xd7, 0xab, 0x00, 0x4e, 0x1c, 0xaa, 0xfd, 0xd7, 0x35, 0x1f, 0x45, 0x79, 0x02, 0x7a, 0x86, 0x1c, 0x7b, 0x1e, 0xbc, 0x13, 0x1f, 0xa6, 0x1e, 0x10, 0x27, 0xcd, 0xb4, 0x20, 0x8d, 0xbd, 0x1e, 0xe1, 0x6b, 0xe2, 0xfb, 0xfd, 0xc5, 0x54, 0xf5, 0x70, 0x54, 0xb9, 0xe2, 0x53, 0xe0, 0x5a, 0x7b, 0xed, 0x0a, 0x7e, 0x24, 0xa8, 0x39, 0x42, 0x5b, 0xa3, 0x90, 0x81, 0x96, 0x15, 0x97, 0xd0, 0x0a, 0x5f, 0x4a, 0x33, 0xfb, 0x1b, 0x73, 0x29, 0x09, 0xa4, 0x8d, 0xb9, 0xcc, 0xf5, 0xcd, 0x5f, 0x0b, 0x41, 0xf2, 0xf7, 0xd1, 0xc9, 0xab, 0x9f, 0x4d, 0x63, 0x38, 0xaa, 0x68, 0x52, 0xcc, 0xe9, 0x3d, 0x72, 0x68, 0xcf, 0xa9, 0x96, 0x9b, 0xa8, 0x63, 0xb3, 0xa9, 0xb2, 0x44, 0x70, 0x92, 0x7d, 0x1c, 0x51, 0x30, 0xb0, 0x3a, 0xd2, 0x28, 0xb1, 0x02, 0x01, 0xf0, 0x0d, 0x28, 0x35, 0x5d, 0x44, 0x3a, 0x1d, 0xc9, 0xc4, 0xc5, 0x1a, 0x3d, 0xd4, 0xdf, 0xb6, 0x1b, 0xbb, 0xb8, 0x38, 0x95, 0xde };
            var es11 = new byte[] { 0x32, 0x12, 0x57, 0x18, 0x87, 0xa2, 0x26, 0x2a, 0x91, 0x3e, 0xf1, 0xa5, 0x07, 0x76, 0x0f, 0x6d, 0xa2, 0x09, 0x6a, 0x7b, 0xa4, 0x59, 0x5d, 0xc6, 0x2b, 0xca, 0x0e, 0xce, 0xd2, 0xf7, 0xb3, 0x4f, 0x01, 0x52, 0x1c, 0x07, 0x59, 0x06, 0x7b, 0x2a, 0x4c, 0x57, 0xeb, 0x45, 0x64, 0x37, 0x9c, 0xe5, 0x22, 0xcd, 0x77, 0x19, 0x29, 0xe3, 0x6e, 0x21, 0xbf, 0x11, 0x40, 0x6a, 0x89, 0xc8, 0x8f, 0xb0, 0x2b, 0x8e, 0x2a, 0x33, 0x2c, 0xce, 0x24, 0x9f, 0xed, 0xec, 0x3a, 0x50, 0xae, 0x69, 0xcd, 0x99, 0xac, 0x92, 0xd7, 0xaa, 0xe7, 0xca, 0xbf, 0x7b, 0xc4, 0x36, 0xd7, 0xd8, 0x16, 0xf4, 0x59, 0x30, 0xc4, 0x8c, 0x10, 0x66, 0x6a, 0xb6, 0xf2, 0x18, 0x69, 0x8c, 0xae, 0x38, 0x32, 0x54, 0x12, 0xcb, 0x5c, 0xc7, 0x92, 0x3b, 0x3a, 0x71, 0xa4, 0xfd, 0x81, 0x46, 0xf6, 0x7d, 0xf9, 0x97, 0xeb, 0xf2, 0x5c, 0xfc, 0x4f, 0x3c, 0x9c, 0x6f, 0xd8, 0x42, 0x24, 0x11, 0x16, 0xbd, 0xaa, 0x38, 0x0f, 0x0e, 0xe2, 0x92, 0x83, 0x54, 0x0f, 0xd3, 0x6e, 0xe5, 0x2a, 0x36, 0x77, 0x14, 0x80, 0x5e, 0xf9, 0x1f, 0x5b, 0xd0, 0xb5, 0xb5, 0x57, 0x5b, 0xf1, 0x79, 0xf8, 0x30, 0x74, 0xb6, 0xbf, 0xcb, 0x4c, 0x66, 0x32, 0xeb, 0x3a, 0xed, 0x80, 0x5b, 0xd6, 0xd8, 0x57, 0xf8, 0xec, 0xf8, 0x53, 0x05, 0x9a, 0xcc, 0x7b, 0x73, 0x9a, 0xfc, 0xe3, 0x40, 0xef, 0xbb, 0x96, 0x7a, 0x98, 0x9d, 0x73, 0x1b, 0x88, 0x40, 0xbd, 0x94, 0xfc, 0x21, 0x0b, 0x0c, 0xba, 0xf6, 0xc8, 0x53, 0x3a, 0xdf, 0x1a, 0x87, 0xdc, 0xfe, 0x15, 0xa7, 0xbc, 0x0e, 0x3b, 0x3a, 0x67, 0x3b, 0x40, 0xfd, 0xab, 0xa8, 0x75, 0xa0, 0xbf, 0x6a };


            var configC = new MicroRatchetConfiguration
            {
                IsClient           = true,
                MaximumMessageSize = 256,
                MinimumMessageSize = 32,
                ApplicationKey     = applicationKey
            };
            var configS = new MicroRatchetConfiguration
            {
                IsClient           = false,
                MaximumMessageSize = 256,
                MinimumMessageSize = 32,
                ApplicationKey     = applicationKey
            };

            var rngC       = new FakeRandomNumberGenerator(randomC);
            var signatureC = new Signature(privateKeyC, new SecureRandom(rngC));
            var rngS       = new FakeRandomNumberGenerator(randomS);
            var signatureS = new Signature(privateKeyS, new SecureRandom(rngS));

            var servicesC = new BouncyCastleServices(privateKeyC)
            {
                Signature             = signatureC,
                RandomNumberGenerator = rngC,
            };

            servicesC.KeyAgreementFactory = new DeterministicKexFac(servicesC.KeyAgreementFactory, rngC);

            var servicesS = new BouncyCastleServices(privateKeyS)
            {
                Signature             = signatureS,
                RandomNumberGenerator = rngS,
            };

            servicesS.KeyAgreementFactory = new DeterministicKexFac(servicesS.KeyAgreementFactory, rngS);

            var C = new MicroRatchetContext(servicesC, configC, null);
            var S = new MicroRatchetContext(servicesS, configS, null);

            var c1 = C.InitiateInitialization();
            var s2 = S.Receive(c1).ToSendBack;
            var c3 = C.Receive(s2).ToSendBack;
            var s4 = S.Receive(c3).ToSendBack;
            var c5 = C.Receive(s4).ToSendBack;

            //BytePrintHelper.PrintAsByteArray("ec1", c1);
            //BytePrintHelper.PrintAsByteArray("es2", s2);
            //BytePrintHelper.PrintAsByteArray("ec3", c3);
            //BytePrintHelper.PrintAsByteArray("es4", s4);

            Assert.Equal(ec1, c1);
            Assert.Equal(es2, s2);
            Assert.Equal(ec3, c3);
            Assert.Equal(es4, s4);
            Assert.Null(c5);

            var c6  = C.Send(message1);
            var s7  = S.Receive(c6).Payload;
            var s8  = S.Send(message2);
            var c9  = C.Receive(s8).Payload;
            var c10 = C.Send(message3);
            var s11 = S.Receive(c10).Payload;

            //BytePrintHelper.PrintAsByteArray("ec6", c6);
            //BytePrintHelper.PrintAsByteArray("es7", s7);
            //BytePrintHelper.PrintAsByteArray("es8", s8);
            //BytePrintHelper.PrintAsByteArray("ec9", c9);
            //BytePrintHelper.PrintAsByteArray("ec10", c10);
            //BytePrintHelper.PrintAsByteArray("es11", s11);

            Assert.Equal(ec6, c6);
            Assert.Equal(es7, s7);
            Assert.Equal(es8, s8);
            Assert.Equal(ec9, c9);
            Assert.Equal(ec10, c10);
            Assert.Equal(es11, s11);

            Assert.Equal(message1, s7);
            Assert.Equal(message2, c9);
            Assert.Equal(message3, s11);
        }
Пример #15
0
        public void ClientMessagesReinstantiation()
        {
            var clientServices = new BouncyCastleServices(KeyGeneration.GeneratePrivateKey());
            var serverServices = new BouncyCastleServices(KeyGeneration.GeneratePrivateKey());

            RandomNumberGenerator rng = new RandomNumberGenerator();

            byte[] message1 = rng.Generate(64);
            byte[] message2 = rng.Generate(64);
            byte[] message3 = rng.Generate(64);

            byte[] s, c;

            var client           = new MicroRatchetContext(clientServices, true);
            var clientInitPacket = client.InitiateInitialization();

            c = client.SaveStateAsByteArray();
            var server         = new MicroRatchetContext(serverServices, false);
            var responsePacket = server.Receive(clientInitPacket).ToSendBack;

            s      = server.SaveStateAsByteArray();
            client = new MicroRatchetContext(clientServices, true, stateBytes: c);
            var firstPacket = client.Receive(responsePacket).ToSendBack;

            c      = client.SaveStateAsByteArray();
            server = new MicroRatchetContext(serverServices, false, stateBytes: s);
            var firstResponse = server.Receive(firstPacket).ToSendBack;

            s      = server.SaveStateAsByteArray();
            client = new MicroRatchetContext(clientServices, true, stateBytes: c);
            var lastResult = client.Receive(firstResponse).ToSendBack;

            c = client.SaveStateAsByteArray();

            client = new MicroRatchetContext(clientServices, true, 80, stateBytes: c);
            var pl1 = client.Send(message1);

            c      = client.SaveStateAsByteArray();
            client = new MicroRatchetContext(clientServices, true, 80, stateBytes: c);
            var pl2 = client.Send(message2);

            c      = client.SaveStateAsByteArray();
            client = new MicroRatchetContext(clientServices, true, 80, stateBytes: c);
            var pl3 = client.Send(message3);

            c = client.SaveStateAsByteArray();

            server = new MicroRatchetContext(serverServices, false, 80, stateBytes: s);
            var r1 = server.Receive(pl1).Payload;

            s      = server.SaveStateAsByteArray();
            server = new MicroRatchetContext(serverServices, false, 80, stateBytes: s);
            var r2 = server.Receive(pl2).Payload;

            s      = server.SaveStateAsByteArray();
            server = new MicroRatchetContext(serverServices, false, 80, stateBytes: s);
            var r3 = server.Receive(pl3).Payload;

            s = server.SaveStateAsByteArray();

            Assert.Equal(message1, r1);
            Assert.Equal(message2, r2);
            Assert.Equal(message3, r3);

            Assert.Null(lastResult);
        }