private static TServerDHParamsOk SerializeResponse(TPQInnerData pqInnerData, TServerDHInnerData dhInnerData)
        {
            var dhInnerDataBuffer = Serializer.Serialize(dhInnerData);

            byte[] answer;
            try
            {
                answer = dhInnerDataBuffer.ToArray();
            }
            finally
            {
                dhInnerDataBuffer.SafeRelease();
            }

            var hashsum = Sha1Helper.ComputeHashsum(answer);

            var answerWithHash = hashsum.Concat(answer).ToArray();

            AesHelper.ComputeAesParameters(pqInnerData.NewNonce, pqInnerData.ServerNonce, out var aesKeyData);

            var encryptedAnswer = AES.EncryptAes(aesKeyData, answerWithHash);

            return(new TServerDHParamsOk
            {
                EncryptedAnswerAsBinary = encryptedAnswer,
                Nonce = pqInnerData.Nonce,
                ServerNonce = pqInnerData.ServerNonce
            });
        }
        public static RequestSetClientDHParams GetRequest(TServerDHParamsOk serverDhParams, byte[] newNonce, out byte[] clientAgree, out int serverTime)
        {
            AesHelper.ComputeAesParameters(newNonce, serverDhParams.ServerNonce, out var aesKeyData);

            var dhInnerData = DeserializeResponse(serverDhParams, aesKeyData);

            serverTime = dhInnerData.ServerTime;

            var p = new BigInteger(1, dhInnerData.DhPrimeAsBinary);
            var g = BigInteger.ValueOf(dhInnerData.G);

            var dhParameters            = new DHParameters(p, g);
            KeyGenerationParameters kgp = new DHKeyGenerationParameters(new SecureRandom(), dhParameters);
            var keyGen = GeneratorUtilities.GetKeyPairGenerator("DH");

            keyGen.Init(kgp);

            var clientKeyPair = keyGen.GenerateKeyPair();
            var publicKey     = ((DHPublicKeyParameters)clientKeyPair.Public);

            var y = new BigInteger(1, dhInnerData.GAAsBinary);

            Guard.That(y).IsValidDhPublicKey(dhParameters.P);

            var serverPublicKey = new DHPublicKeyParameters(y, dhParameters);
            var clientKeyAgree  = AgreementUtilities.GetBasicAgreement("DH");

            clientKeyAgree.Init(clientKeyPair.Private);
            clientAgree = clientKeyAgree.CalculateAgreement(serverPublicKey).ToByteArrayUnsigned();

            var clientDhInnerData = new TClientDHInnerData
            {
                RetryId     = 0,
                Nonce       = serverDhParams.Nonce,
                ServerNonce = serverDhParams.ServerNonce,
                GBAsBinary  = publicKey.Y.ToByteArray()
            };

            return(SerializeRequest(clientDhInnerData, aesKeyData));
        }
        public static ISetClientDHParamsAnswer GetResponse(RequestSetClientDHParams setClientDhParams, byte[] newNonce, AsymmetricCipherKeyPair serverKeyPair, out BigInteger serverAgree, out byte[] serverSalt)
        {
            AesHelper.ComputeAesParameters(newNonce, setClientDhParams.ServerNonce, out var aesKeyData);

            var dhInnerData = DeserializeRequest(setClientDhParams, aesKeyData);

            var dhParameters = ((DHPrivateKeyParameters)serverKeyPair.Private).Parameters;

            var y = new BigInteger(dhInnerData.GBAsBinary);

            Guard.That(y).IsValidDhPublicKey(dhParameters.P);

            var clientPublicKey = new DHPublicKeyParameters(y, dhParameters);

            var serverKeyAgree = AgreementUtilities.GetBasicAgreement("DH");

            serverKeyAgree.Init(serverKeyPair.Private);

            serverAgree = serverKeyAgree.CalculateAgreement(clientPublicKey);

            serverSalt = SaltHelper.ComputeSalt(newNonce, setClientDhParams.ServerNonce);

            return(SerializeResponse(setClientDhParams, newNonce, serverAgree));
        }