public override CommandResult Execute()
        {
            var datagrams = Pcap.ReadFile(PcapFile).
                            TrySelect(record =>
                                      Tx.Network.PacketParser.Parse(record.Data.Skip(14).ToArray())).
                            Where(p => p != null).
                            Where(p => p.ProtocolType == ProtocolType.Udp).
                            Select(p => p.ToUdpDatagram()).
                            Where(p => p.UdpDatagramHeader.SourcePort == Port ||
                                  p.UdpDatagramHeader.DestinationPort == Port).
                            ToArray();

            var cryptoBlob = SharedSecret.HexToBytes();

            var decryptor = new MessageAnalyzer(cryptoBlob);

            foreach (var datagram in datagrams)
            {
                var messageInfo = decryptor.ReadMessage(datagram.UdpData.ToArray());
                Console.WriteLine($"From: {datagram.UdpDatagramHeader.SourcePort}, To: {datagram.UdpDatagramHeader.DestinationPort}");
                Console.WriteLine($"Message Type: {messageInfo.MessageType}");
                Console.WriteLine($"Request Ack: {messageInfo.RequestAcknowledge}");
                Console.WriteLine($"Version: {messageInfo.Version}");
                Console.WriteLine($"ChannelId: {messageInfo.ChannelId}");

                if (!String.IsNullOrEmpty(messageInfo.Json))
                {
                    Console.WriteLine($"Json: {messageInfo.Json}");
                }
                else
                {
                    Console.WriteLine($"Binary: {messageInfo.Data.ToHex()}");
                }

                Console.WriteLine();
            }

            return(CommandResult.Success);
        }
Beispiel #2
0
        public static void BitMaskedAgree(string privateKey, string publicKey, string sharedSecret)
        {
            var a   = KeyAgreementAlgorithm.X25519;
            var kdf = KeyDerivationAlgorithm.HkdfSha256;

            var pk1 = publicKey.DecodeHex();
            var pk2 = publicKey.DecodeHex();

            pk1[pk1.Length - 1] &= 0x7F;
            pk2[pk2.Length - 1] |= 0x80;

            using var k = Key.Import(a, privateKey.DecodeHex(), KeyBlobFormat.RawPrivateKey);
            using var sharedSecretExpected = SharedSecret.Import(sharedSecret.DecodeHex());
            using var sharedSecretActual1  = a.Agree(k, PublicKey.Import(a, pk1, KeyBlobFormat.RawPublicKey)) ?? throw new Xunit.Sdk.NotNullException();
            using var sharedSecretActual2  = a.Agree(k, PublicKey.Import(a, pk2, KeyBlobFormat.RawPublicKey)) ?? throw new Xunit.Sdk.NotNullException();

            var expected = kdf.Extract(sharedSecretExpected, ReadOnlySpan <byte> .Empty);
            var actual1  = kdf.Extract(sharedSecretActual1, ReadOnlySpan <byte> .Empty);
            var actual2  = kdf.Extract(sharedSecretActual2, ReadOnlySpan <byte> .Empty);

            Assert.Equal(expected, actual1);
            Assert.Equal(expected, actual2);
        }
        public byte[] decrypt(byte[] data)
        {
            SharedSecret secret = SharedSecret.Import(motherKey);

            byte[] seconds = new byte[4];
            Array.Copy(data, 0, seconds, 0, 4);
            Console.WriteLine("Seconds size: " + seconds.Length);
            Console.WriteLine("Seconds: " + BitConverter.ToInt32(seconds));

            byte[] IV = new byte[12];
            Array.Copy(data, 4, IV, 0, 12);
            Console.WriteLine("IV size: " + IV.Length);
            Console.WriteLine("IV: " + BitConverter.ToString(IV));

            byte[] ciphertext = new byte[data.Length - 16];
            Array.Copy(data, 16, ciphertext, 0, ciphertext.Length);
            Console.WriteLine("Ciphertext size: " + ciphertext.Length);
            Console.WriteLine("Ciphertext: " + BitConverter.ToString(ciphertext));

            Key keyCipher = KeyDerivationAlgorithm.HkdfSha256.DeriveKey(secret, seconds, null, ChaCha20Poly1305.ChaCha20Poly1305);

            byte[] plaintext = new byte[ciphertext.Length - ChaCha20Poly1305.ChaCha20Poly1305.TagSize];

            bool decrypt = ChaCha20Poly1305.ChaCha20Poly1305.Decrypt(keyCipher, new Nonce(IV, 0), null, ciphertext, plaintext);

            if (decrypt)
            {
                Console.WriteLine("Decryption successful, plaintext: " + BitConverter.ToString(plaintext));
                return(plaintext);
            }
            else
            {
                Console.WriteLine("Decryption unsuccessful");
                return(null);
            }
        }
Beispiel #4
0
        public static void BitMaskedAgree(string privateKey, string publicKey, string sharedSecret)
        {
            var a   = new X25519();
            var kdf = new HkdfSha256();

            var pk1 = publicKey.DecodeHex();
            var pk2 = publicKey.DecodeHex();

            pk1[pk1.Length - 1] &= 0x7F;
            pk2[pk2.Length - 1] |= 0x80;

            using (var k = Key.Import(a, privateKey.DecodeHex(), KeyBlobFormat.RawPrivateKey))
                using (var sharedSecretExpected = SharedSecret.Import(sharedSecret.DecodeHex()))
                    using (var sharedSecretActual1 = a.Agree(k, PublicKey.Import(a, pk1, KeyBlobFormat.RawPublicKey)))
                        using (var sharedSecretActual2 = a.Agree(k, PublicKey.Import(a, pk2, KeyBlobFormat.RawPublicKey)))
                        {
                            var expected = kdf.Extract(sharedSecretExpected, ReadOnlySpan <byte> .Empty);
                            var actual1  = kdf.Extract(sharedSecretActual1, ReadOnlySpan <byte> .Empty);
                            var actual2  = kdf.Extract(sharedSecretActual2, ReadOnlySpan <byte> .Empty);

                            Assert.Equal(expected, actual1);
                            Assert.Equal(expected, actual2);
                        }
        }
        internal Tlv HandlePairSetupM5Raw(ConnectionSession session, out KeyPair keyPair)
        {
            var hdkf      = new HkdfSha512();
            var accessory = hdkf.DeriveBytes(
                SharedSecret.Import(SrpInteger.FromHex(session.ServerSession.Key).ToByteArray()),
                Encoding.UTF8.GetBytes("Pair-Setup-Accessory-Sign-Salt"),
                Encoding.UTF8.GetBytes("Pair-Setup-Accessory-Sign-Info"), 32);

            keyPair = KeyGenerator.GenerateNewPair();

            var serverUsername = Encoding.UTF8.GetBytes(HapControllerServer.HapControllerId);
            var material       = accessory.Concat(serverUsername).Concat(keyPair.PublicKey).ToArray();

            var signature = Chaos.NaCl.Ed25519.Sign(material, keyPair.PrivateKey);


            var encoder = new Tlv();

            encoder.AddType(Constants.Identifier, serverUsername);
            encoder.AddType(Constants.PublicKey, keyPair.PublicKey);
            encoder.AddType(Constants.Signature, signature);

            return(encoder);
        }
        public PairSetupReturn Post(Tlv parts)
        {
            var customParams = SrpParameters.Create3072 <SHA512>();

            var state = parts.GetTypeAsInt(Constants.State);

            if (state == 1) //srp sign up
            {
                var rnd = new Random();
                _salt = new byte[16];
                rnd.NextBytes(_salt);

                _saltInt = SrpInteger.FromByteArray(_salt);

                var srp = new SrpClient(customParams);
                _privateKey = srp.DerivePrivateKey(_saltInt.ToHex(), Username, _code);
                _verifier   = srp.DeriveVerifier(_privateKey);

                _server          = new SrpServer(customParams);
                _serverEphemeral = _server.GenerateEphemeral(_verifier);

                var responseTlv = new Tlv();
                responseTlv.AddType(Constants.State, 2);
                responseTlv.AddType(Constants.PublicKey, StringToByteArray(_serverEphemeral.Public));
                responseTlv.AddType(Constants.Salt, _salt);

                return(new PairSetupReturn
                {
                    State = 1,
                    TlvData = responseTlv,
                    Ok = true
                });
            }

            if (state == 3) //srp authenticate
            {
                _logger.LogDebug("Pair Setup Step 3/6");
                _logger.LogDebug("SRP Verify Request");

                var pubKey = parts.GetType(Constants.PublicKey);
                var proof  = parts.GetType(Constants.Proof);

                var iOsPublicKey = SrpInteger.FromByteArray(pubKey);
                var iOsProof     = SrpInteger.FromByteArray(proof);


                var responseTlv = new Tlv();
                responseTlv.AddType(Constants.State, 4);
                var ok = true;
                try
                {
                    _serverSession = _server.DeriveSession(_serverEphemeral.Secret, iOsPublicKey.ToHex(), _saltInt.ToHex(), Username, _verifier,
                                                           iOsProof.ToHex());
                    _logger.LogInformation("Verification was successful. Generating Server Proof (M2)");

                    responseTlv.AddType(Constants.Proof, StringToByteArray(_serverSession.Proof));
                }
                catch (Exception)
                {
                    ok = false;
                    _logger.LogError("Verification failed as iOS provided code was incorrect");
                    responseTlv.AddType(Constants.Error, ErrorCodes.Authentication);
                }
                return(new PairSetupReturn
                {
                    State = 3,
                    Ok = ok,
                    TlvData = responseTlv
                });
            }

            if (state == 5)
            {
                _logger.LogDebug("Pair Setup Step 5/6");
                _logger.LogDebug("Exchange Response");

                try
                {
                    var iOsEncryptedData = parts.GetType(Constants.EncryptedData).AsSpan(); // A
                    var zeros            = new byte[] { 0, 0, 0, 0 };
                    var nonce            = new Nonce(zeros, Encoding.UTF8.GetBytes("PS-Msg05"));
                    var hdkf             = new HkdfSha512();
                    var hkdfEncKey       = hdkf.DeriveBytes(
                        SharedSecret.Import(SrpInteger.FromHex(_serverSession.Key).ToByteArray()),
                        Encoding.UTF8.GetBytes("Pair-Setup-Encrypt-Salt"),
                        Encoding.UTF8.GetBytes("Pair-Setup-Encrypt-Info"), 32);


                    var decrypt = AeadAlgorithm.ChaCha20Poly1305.Decrypt(
                        Key.Import(AeadAlgorithm.ChaCha20Poly1305, hkdfEncKey, KeyBlobFormat.RawSymmetricKey), nonce,
                        new byte[0], iOsEncryptedData, out var output);
                    var responseTlv = new Tlv();
                    responseTlv.AddType(Constants.State, 6);
                    if (!decrypt)
                    {
                        responseTlv.AddType(Constants.Error, ErrorCodes.Authentication);
                        return(new PairSetupReturn
                        {
                            State = 5,
                            TlvData = responseTlv,
                            Ok = false
                        });
                    }

                    var subData = TlvParser.Parse(output);

                    byte[] username = subData.GetType(Constants.Identifier);
                    byte[] ltpk     = subData.GetType(Constants.PublicKey);
                    byte[] proof    = subData.GetType(Constants.Signature);


                    var okm = hdkf.DeriveBytes(
                        SharedSecret.Import(SrpInteger.FromHex(_serverSession.Key).ToByteArray()),
                        Encoding.UTF8.GetBytes("Pair-Setup-Controller-Sign-Salt"),
                        Encoding.UTF8.GetBytes("Pair-Setup-Controller-Sign-Info"), 32);

                    var completeData = okm.Concat(username).Concat(ltpk).ToArray();


                    if (!SignatureAlgorithm.Ed25519.Verify(
                            PublicKey.Import(SignatureAlgorithm.Ed25519, ltpk, KeyBlobFormat.RawPublicKey), completeData,
                            proof))
                    {
                        var errorTlv = new Tlv();
                        errorTlv.AddType(Constants.Error, ErrorCodes.Authentication);
                        return(new PairSetupReturn
                        {
                            State = 5,
                            TlvData = errorTlv,
                            Ok = false
                        });
                    }

                    var accessory = hdkf.DeriveBytes(
                        SharedSecret.Import(SrpInteger.FromHex(_serverSession.Key).ToByteArray()),
                        Encoding.UTF8.GetBytes("Pair-Setup-Accessory-Sign-Salt"),
                        Encoding.UTF8.GetBytes("Pair-Setup-Accessory-Sign-Info"), 32);


                    var seed = new byte[32];
                    RandomNumberGenerator.Create().GetBytes(seed);
                    Chaos.NaCl.Ed25519.KeyPairFromSeed(out var accessoryLtpk, out var accessoryLtsk, seed);

                    var serverUsername = Encoding.UTF8.GetBytes(HapControllerServer.HapControllerId);
                    var material       = accessory.Concat(serverUsername).Concat(accessoryLtpk).ToArray();

                    var signature = Chaos.NaCl.Ed25519.Sign(material, accessoryLtsk);


                    var encoder = new Tlv();
                    encoder.AddType(Constants.Identifier, serverUsername);
                    encoder.AddType(Constants.PublicKey, accessoryLtpk);
                    encoder.AddType(Constants.Signature, signature);

                    var plaintext = TlvParser.Serialise(encoder);

                    var nonce6 = new Nonce(zeros, Encoding.UTF8.GetBytes("PS-Msg06"));

                    var encryptedOutput = AeadAlgorithm.ChaCha20Poly1305.Encrypt(
                        Key.Import(AeadAlgorithm.ChaCha20Poly1305, hkdfEncKey, KeyBlobFormat.RawSymmetricKey), nonce6,
                        new byte[0], plaintext);

                    responseTlv.AddType(Constants.EncryptedData, encryptedOutput);

                    return(new PairSetupReturn
                    {
                        State = 5,
                        TlvData = responseTlv,
                        Ok = true,
                        Ltsk = ByteArrayToString(accessoryLtsk),
                        Ltpk = ByteArrayToString(ltpk)
                    });
                }
                catch (Exception e)
                {
                    _logger.LogError(e, "Could not exchange request");
                    throw;
                }
            }

            return(null);
        }
Beispiel #7
0
        public static void ImportTooLong()
        {
            var b = new byte[129];

            Assert.Throws <ArgumentException>("sharedSecret", () => SharedSecret.Import(b));
        }
        internal async Task <Guid> AddFromUrlAsync(string projectName, string @event, EventFilters filters, Uri targetUrl, string ruleName, bool impersonateExecution, CancellationToken cancellationToken)
        {
            async Task <(Uri, string)> RetrieveHostedUrl(string _ruleName, CancellationToken _cancellationToken)
            {
                string apiKey = MagicConstants.InvalidApiKey;

                logger.WriteVerbose($"Validating target URL {targetUrl.AbsoluteUri}");

                string userManagedPassword = Environment.GetEnvironmentVariable(MagicConstants.EnvironmentVariable_SharedSecret);

                if (string.IsNullOrEmpty(userManagedPassword))
                {
                    throw new ApplicationException($"{MagicConstants.EnvironmentVariable_SharedSecret} environment variable is required for this command");
                }

                string proof = SharedSecret.DeriveFromPassword(userManagedPassword);

                var configUrl = new UriBuilder(targetUrl);

                configUrl.Path += $"config/key";
                var handler = new HttpClientHandler()
                {
                    SslProtocols = SslProtocols.Tls12,// | SslProtocols.Tls11 | SslProtocols.Tls,
                    ServerCertificateCustomValidationCallback = delegate { return(true); }
                };

                using (var client = new HttpClient(handler))
                    using (var request = new HttpRequestMessage(HttpMethod.Post, configUrl.Uri))
                    {
                        using (request.Content = new StringContent($"\"{proof}\"", Encoding.UTF8, "application/json"))
                            using (var response = await client.SendAsync(request, cancellationToken))
                            {
                                switch (response.StatusCode)
                                {
                                case HttpStatusCode.OK:
                                    logger.WriteVerbose($"Connection to {targetUrl} succeded");
                                    apiKey = await response.Content.ReadAsStringAsync();

                                    logger.WriteInfo($"Configuration retrieved.");
                                    break;

                                default:
                                    logger.WriteError($"{targetUrl} returned {response.ReasonPhrase}.");
                                    break;
                                }//switch
                            }
                    }

                if (string.IsNullOrEmpty(apiKey) || apiKey == MagicConstants.InvalidApiKey)
                {
                    throw new ApplicationException("Unable to retrieve API Key, please check Shared secret configuration");
                }

                var b = new UriBuilder(targetUrl);

                b.Path += $"workitem/{_ruleName}";
                return(b.Uri, apiKey);
            }

            return(await CoreAddAsync(projectName, @event, filters, ruleName, impersonateExecution, RetrieveHostedUrl, MagicConstants.ApiKeyAuthenticationHeaderName, cancellationToken));
        }
Beispiel #9
0
        public PairVerifyReturn Post(Tlv parts, HapSession session)
        {
            var state = parts.GetTypeAsInt(Constants.State);

            if (state == 1)
            {
                _logger.LogDebug("* Pair Verify Step 1/4");
                _logger.LogDebug("* Verify Start Request");

                var clientPublicKey = parts.GetType(Constants.PublicKey);

                byte[] privateKey = new byte[32];

                Random random = new Random();
                random.NextBytes(privateKey);

                var publicKey    = Curve25519.GetPublicKey(privateKey);
                var sharedSecret = Curve25519.GetSharedSecret(privateKey, clientPublicKey);

                var serverUsername = Encoding.UTF8.GetBytes(HapControllerServer.HapControllerId);

                var material      = publicKey.Concat(serverUsername).Concat(clientPublicKey).ToArray();
                var accessoryLtsk = StringToByteArray(HapControllerServer.HapControllerLtsk);

                var proof = Chaos.NaCl.Ed25519.Sign(material, accessoryLtsk);

                var hdkf       = new HkdfSha512();
                var hkdfEncKey = hdkf.DeriveBytes(SharedSecret.Import(sharedSecret), Encoding.UTF8.GetBytes("Pair-Verify-Encrypt-Salt"),
                                                  Encoding.UTF8.GetBytes("Pair-Verify-Encrypt-Info"), 32);

                var encoder = new Tlv();
                encoder.AddType(Constants.Identifier, serverUsername);
                encoder.AddType(Constants.Signature, proof);
                var plaintext = TlvParser.Serialize(encoder);

                var zeros = new byte[] { 0, 0, 0, 0 };
                var nonce = new Nonce(zeros, Encoding.UTF8.GetBytes("PV-Msg02"));

                var encryptedOutput = AeadAlgorithm.ChaCha20Poly1305.Encrypt(
                    Key.Import(AeadAlgorithm.ChaCha20Poly1305, hkdfEncKey, KeyBlobFormat.RawSymmetricKey), nonce,
                    new byte[0], plaintext);

                var responseTlv = new Tlv();
                responseTlv.AddType(Constants.State, 2);
                responseTlv.AddType(Constants.EncryptedData, encryptedOutput);
                responseTlv.AddType(Constants.PublicKey, publicKey);

                // Store the details on the session.
                //
                session.ClientPublicKey = clientPublicKey;
                session.PrivateKey      = privateKey;
                session.PublicKey       = publicKey;
                session.SharedSecret    = sharedSecret;
                session.HkdfPairEncKey  = hkdfEncKey;


                var encSalt   = Encoding.UTF8.GetBytes("Control-Salt");
                var infoRead  = Encoding.UTF8.GetBytes("Control-Read-Encryption-Key");
                var infoWrite = Encoding.UTF8.GetBytes("Control-Write-Encryption-Key");

                session.AccessoryToControllerKey = hdkf.DeriveBytes(SharedSecret.Import(sharedSecret), encSalt, infoRead, 32);
                session.ControllerToAccessoryKey = hdkf.DeriveBytes(SharedSecret.Import(sharedSecret), encSalt, infoWrite, 32);

                return(new PairVerifyReturn
                {
                    TlvData = responseTlv,
                    Ok = true,
                    HapSession = session
                });
            }

            if (state == 3)
            {
                _logger.LogDebug("* Pair Verify Step 3/4");
                _logger.LogDebug("* Verify Finish Request");

                var encryptedData = parts.GetType(Constants.EncryptedData);
                var zeros         = new byte[] { 0, 0, 0, 0 };
                var nonce         = new Nonce(zeros, Encoding.UTF8.GetBytes("PV-Msg03"));

                var decrypt = AeadAlgorithm.ChaCha20Poly1305.Decrypt(Key.Import(AeadAlgorithm.ChaCha20Poly1305, session.HkdfPairEncKey, KeyBlobFormat.RawSymmetricKey), nonce, new byte[0], encryptedData, out var output);

                if (!decrypt)
                {
                    var errorTlv = new Tlv();
                    errorTlv.AddType(Constants.State, 4);
                    errorTlv.AddType(Constants.Error, ErrorCodes.Authentication);
                    return(new PairVerifyReturn
                    {
                        TlvData = errorTlv,
                        Ok = false
                    });
                }

                var subData        = TlvParser.Parse(output);
                var clientUserName = subData.GetType(Constants.Identifier);
                var signature      = subData.GetType(Constants.Signature);

                var clientPublicKey = StringToByteArray(HapControllerServer.HapControllerLtpk);
                var material        = session.ClientPublicKey.Concat(clientUserName).Concat(session.PublicKey).ToArray();

                session.ClientUsername = Automatica.Core.Driver.Utility.Utils.ByteArrayToString(in clientUserName);

                if (!Chaos.NaCl.Ed25519.Verify(signature, material, clientPublicKey))
                {
                    var errorTlv = new Tlv();
                    errorTlv.AddType(Constants.State, 4);
                    errorTlv.AddType(Constants.Error, ErrorCodes.Authentication);
                    return(new PairVerifyReturn
                    {
                        TlvData = errorTlv,
                        Ok = false
                    });
                }

                var responseTlv = new Tlv();
                responseTlv.AddType(Constants.State, 4);

                session.IsVerified          = true;
                session.SkipFirstEncryption = true;

                return(new PairVerifyReturn
                {
                    Ok = true,
                    TlvData = responseTlv
                });
            }

            return(null);
        }
Beispiel #10
0
 public static void ImportEmpty()
 {
     using var s = SharedSecret.Import(ReadOnlySpan <byte> .Empty);
     Assert.NotNull(s);
     Assert.Equal(0, s.Size);
 }
Beispiel #11
0
        static void Main(string[] args)
        {
            Channel channel = new Channel("ac.testnet.libra.org:8000", ChannelCredentials.Insecure);
            var     client  = new AdmissionControl.AdmissionControl.AdmissionControlClient(channel);

            HexEncoder hex = new HexEncoder();

            SharedSecret sharedSecret = SharedSecret.Import(Encoding.UTF8.GetBytes("newdummy"));
            HkdfSha512   kdf          = new HkdfSha512();
            var          key          = kdf.DeriveKey(sharedSecret, null, null, Ed25519.Ed25519);
            var          sender       = key.PublicKey.Export(KeyBlobFormat.RawPublicKey);

            UInt64 seqNum    = 11;
            string senderHex = hex.EncodeData(Sha3.Sha3256().ComputeHash(sender));

            uint   amount  = 10000000;
            string reciver = "4ba2555fd146e79e37fda7a2f30dc1b4f3d9228aa48b230dbab0a18d407f2f9b";

            RawTransactionLCS rawTr = new RawTransactionLCS()
            {
                ExpirationTime = (ulong)DateTimeOffset.UtcNow.AddSeconds(60)
                                 .ToUnixTimeSeconds(),
                GasUnitPrice   = 0,
                MaxGasAmount   = 100000,
                SequenceNumber = seqNum
            };

            rawTr.TransactionPayload = new TransactionPayloadLCS();

            rawTr.TransactionPayload.PayloadType = (uint)TransactionPayloadLCSEnum.Script;
            rawTr.TransactionPayload.Script      = new ScriptLCS()
            {
                Code = Utilities.PtPTrxBytecode,
                TransactionArguments = new List <TransactionArgumentLCS>()
                {
                    new TransactionArgumentLCS()
                    {
                        ArgType = (uint)TransactionArgumentLCSEnum.Address,
                        Address = new AddressLCS(reciver)
                    },
                    new TransactionArgumentLCS()
                    {
                        ArgType = (uint)TransactionArgumentLCSEnum.U64,
                        U64     = amount
                    }
                }
            };

            rawTr.Sender = new AddressLCS(senderHex);

            var bytesTrx = LCSCore.LCSSerialization(rawTr);

            Types.SignedTransaction signedTx = new Types.SignedTransaction();
            var bytesTrxHash = Google.Protobuf.ByteString.CopyFrom(bytesTrx);

            var         seed      = Encoding.ASCII.GetBytes(RAWTX_HASH_SALT + LIBRA_HASH_SUFFIX);
            var         seedHash  = Sha3.Sha3256().ComputeHash(seed);
            List <byte> hashInput = new List <byte>();

            hashInput.AddRange(seedHash);
            hashInput.AddRange(bytesTrxHash);
            var hash = Sha3.Sha3256().ComputeHash(hashInput.ToArray());

            SubmitTransactionRequest req = new SubmitTransactionRequest();

            req.SignedTxn = new SignedTransaction();

            List <byte> retArr = new List <byte>();

            retArr = retArr.Concat(bytesTrx).ToList();

            retArr = retArr.Concat(
                LCSCore.LCSSerialization(key.Export(KeyBlobFormat.RawPublicKey))).ToList();
            var sig = SignatureAlgorithm.Ed25519.Sign(key, hash);

            retArr = retArr.Concat(LCSCore.LCSSerialization(sig)).ToList();
            req.SignedTxn.SignedTxn = ByteString.CopyFrom(retArr.ToArray());


            var result = client.SubmitTransaction(
                req, new Metadata());

            Task.Delay(5000).Wait();
            GetTransaction(client, senderHex, seqNum);
        }
        internal PairSetupReturn HandlePairSetupM5(Tlv parts, ConnectionSession session)
        {
            _logger.LogDebug("Pair Setup Step 5/5");
            _logger.LogDebug("Exchange Response");

            try
            {
                var iOsEncryptedData = parts.GetType(Constants.EncryptedData).AsSpan(); // A
                var zeros            = new byte[] { 0, 0, 0, 0 };
                var nonce            = new Nonce(zeros, Encoding.UTF8.GetBytes("PS-Msg05"));
                var hdkf             = new HkdfSha512();
                var hkdfEncKey       = hdkf.DeriveBytes(
                    SharedSecret.Import(SrpInteger.FromHex(session.ServerSession.Key).ToByteArray()),
                    Encoding.UTF8.GetBytes("Pair-Setup-Encrypt-Salt"),
                    Encoding.UTF8.GetBytes("Pair-Setup-Encrypt-Info"), 32);


                var decrypt = AeadAlgorithm.ChaCha20Poly1305.Decrypt(
                    Key.Import(AeadAlgorithm.ChaCha20Poly1305, hkdfEncKey, KeyBlobFormat.RawSymmetricKey), nonce,
                    new byte[0], iOsEncryptedData, out var output);
                var responseTlv = new Tlv();
                responseTlv.AddType(Constants.State, 6);
                if (!decrypt)
                {
                    responseTlv.AddType(Constants.Error, ErrorCodes.Authentication);
                    return(new PairSetupReturn
                    {
                        State = 5,
                        TlvData = responseTlv,
                        Ok = false
                    });
                }

                var subData = TlvParser.Parse(output);

                byte[] username = subData.GetType(Constants.Identifier);
                byte[] ltpk     = subData.GetType(Constants.PublicKey);
                byte[] proof    = subData.GetType(Constants.Signature);


                var okm = hdkf.DeriveBytes(
                    SharedSecret.Import(SrpInteger.FromHex(session.ServerSession.Key).ToByteArray()),
                    Encoding.UTF8.GetBytes("Pair-Setup-Controller-Sign-Salt"),
                    Encoding.UTF8.GetBytes("Pair-Setup-Controller-Sign-Info"), 32);

                var completeData = okm.Concat(username).Concat(ltpk).ToArray();


                if (!SignatureAlgorithm.Ed25519.Verify(
                        PublicKey.Import(SignatureAlgorithm.Ed25519, ltpk, KeyBlobFormat.RawPublicKey), completeData,
                        proof))
                {
                    var errorTlv = new Tlv();
                    errorTlv.AddType(Constants.Error, ErrorCodes.Authentication);
                    return(new PairSetupReturn
                    {
                        State = 5,
                        TlvData = errorTlv,
                        Ok = false
                    });
                }

                var m5Response = HandlePairSetupM5Raw(session, out var keyPair);
                var plaintext  = TlvParser.Serialize(m5Response);

                _logger.LogDebug($"Decrypted payload {Automatica.Core.Driver.Utility.Utils.ByteArrayToString(plaintext.AsSpan())}");


                var nonce6 = new Nonce(zeros, Encoding.UTF8.GetBytes("PS-Msg06"));

                var encryptedOutput = AeadAlgorithm.ChaCha20Poly1305.Encrypt(
                    Key.Import(AeadAlgorithm.ChaCha20Poly1305, hkdfEncKey, KeyBlobFormat.RawSymmetricKey), nonce6,
                    new byte[0], plaintext);

                responseTlv.AddType(Constants.EncryptedData, encryptedOutput);

                return(new PairSetupReturn
                {
                    State = 5,
                    TlvData = responseTlv,
                    Ok = true,
                    Ltsk = ByteArrayToString(keyPair.PrivateKey),
                    Ltpk = ByteArrayToString(ltpk)
                });
            }
            catch (Exception e)
            {
                _logger.LogError(e, $"{e}, Could not exchange request");
                throw;
            }
        }